package com.yanqu.road.server.manager.activity.langyabang;

import com.alibaba.fastjson.JSON;
import com.yanqu.road.entity.activity.langyabang.config.*;
import com.yanqu.road.entity.activity.langyabang.data.*;
import com.yanqu.road.entity.activity.langyabang.entity.LangYaTypePatrons;
import com.yanqu.road.entity.activity.langyabang.entity.LangYaUserBuilding;
import com.yanqu.road.entity.activity.langyabang.entity.LangYaUserEvent;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.enums.activity.langyabang.eLangYaBangBuildingBuffType;
import com.yanqu.road.entity.enums.activity.langyabang.eLangYaBangEventType;
import com.yanqu.road.entity.enums.activity.langyabang.eLangYaNoticeType;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.log.langyabang.*;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.rank.yrank.UnionYRank;
import com.yanqu.road.entity.union.UnionBaseInfo;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroup;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroupUnion;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroupUser;
import com.yanqu.road.logic.bussiness.DaoHelper;
import com.yanqu.road.logic.bussiness.activity.LangYaBangBusiness;
import com.yanqu.road.logic.helper.CalcPowerResult;
import com.yanqu.road.logic.helper.PowerHelper;
import com.yanqu.road.logic.pb.LangYaBangPb;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.logic.pb.UnionBasePb;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.pb.activity.LangYaBangProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.activity.langyabang.log.LogCrossLangYaBang;
import com.yanqu.road.server.manager.config.GoodsMgr;
import com.yanqu.road.server.manager.union.activitygroup.Cross2UnionActivityGroupMgr;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.manager.yrank.CrossYRankMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public class LangYaBangActivity {

    private static Logger logger = LogManager.getLogger(LangYaBangActivity.class.getName());

    private int activityId;

    private int groupId;

    private Random random = new Random();

    private AtomicInteger declareWarUid;

    RandomHelper randomHelper = new RandomHelper();

    private Map<Long, LangYaBangUserData> userDataMap = new ConcurrentHashMap<>();

    private Map<String, LangYaUnionData> unionMap = new ConcurrentHashMap<>();

    private Map<String, Map<Integer, LangYaBangDeclareWarData>> declareWarDataMap = new ConcurrentHashMap<>();

    private Map<String, Map<Integer, LangYaBangDeclareWarData>> overTimeDeclareWarDataMap = new ConcurrentHashMap<>();

    private List<LangYaDeclareWarNoticeData> noticeDataList = new ArrayList<>();

    private List<LangYaDeclareWarNoticeData> needInsertNoticeDataList = new ArrayList<>();

    public boolean loadDbData() {
        userDataMap = LangYaBangBusiness.getLangYaUserData(activityId, groupId);
        unionMap = LangYaBangBusiness.getLangYaUnionData(activityId, groupId);
        declareWarDataMap = LangYaBangBusiness.getNoEndLangYaBangDeclareWarData(activityId, groupId);
        overTimeDeclareWarDataMap = LangYaBangBusiness.getLangYaBangOverTimeDeclareWarData(activityId, groupId);
        int maxUid = getMaxUid();
        declareWarUid = new AtomicInteger(maxUid + 1);
        noticeDataList = LangYaBangBusiness.getLangYaDeclareWarNoticeData(activityId,groupId,CrossLangYaBangConfigMgr.getMaxNoticeAndReportNum(activityId));
        noticeDataList.sort(Comparator.comparing(LangYaDeclareWarNoticeData::getTime));
        return true;
    }

    public boolean save() {

        for (LangYaBangUserData langYaBangUserData : userDataMap.values()) {
            if (langYaBangUserData.isInsertOption()) {
                LangYaBangBusiness.addLangYaUserData(langYaBangUserData);
            } else if (langYaBangUserData.isUpdateOption()) {
                LangYaBangBusiness.updateLangYaUserData(langYaBangUserData);
            }
        }

        for (LangYaUnionData langYaUnionData : unionMap.values()) {
            if (langYaUnionData.isInsertOption()) {
                LangYaBangBusiness.addLangYaUnionData(langYaUnionData);
            } else if (langYaUnionData.isUpdateOption()) {
                LangYaBangBusiness.updateLangYaUnionData(langYaUnionData);
            }
        }

        for (Map<Integer, LangYaBangDeclareWarData> noEndDeclareWarMap : declareWarDataMap.values()) {
            for (LangYaBangDeclareWarData data : noEndDeclareWarMap.values()) {
                if (data.isUpdateOption()) {
                    LangYaBangBusiness.updateLangYaBangDeclareWarData(data);
                } else if (data.isInsertOption()) {
                    LangYaBangBusiness.addLangYaBangDeclareWarData(data);
                }
            }
        }

        for (Map<Integer, LangYaBangDeclareWarData> endDeclareWarMap : overTimeDeclareWarDataMap.values()) {
            for (LangYaBangDeclareWarData data : endDeclareWarMap.values()) {
                if (data.isUpdateOption()) {
                    LangYaBangBusiness.updateLangYaBangDeclareWarData(data);
                } else if (data.isInsertOption()) {
                    LangYaBangBusiness.addLangYaBangDeclareWarData(data);
                }
            }
        }

        List<LangYaDeclareWarNoticeData> insertNoticeDataList = new ArrayList<>();
        synchronized (needInsertNoticeDataList){
            insertNoticeDataList.addAll(needInsertNoticeDataList);
            needInsertNoticeDataList.clear();
        }
        for (LangYaDeclareWarNoticeData data: insertNoticeDataList){
            if (data.isInsertOption()){
                LangYaBangBusiness.addLangYaDeclareWarNoticeData(data);
            }
//            else {
//                LangYaBangBusiness.updateLangYaDeclareWarNoticeData(data);
//            }
        }

        try {
            LogCrossLangYaBang.save();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 取出最大的宣战uid
     * @return
     */

    private int getMaxUid() {
        int maxNum = 0;
        for (Map<Integer, LangYaBangDeclareWarData> map : declareWarDataMap.values()) {
            for (int uid : map.keySet()) {
                if (uid > maxNum) {
                    maxNum = uid;
                }
            }
        }
        for (Map<Integer, LangYaBangDeclareWarData> map : overTimeDeclareWarDataMap.values()) {
            for (int uid : map.keySet()) {
                if (uid > maxNum) {
                    maxNum = uid;
                }
            }
        }
        return maxNum;
    }

    /**
     * 处理事务时拿的userData
     * @param userId
     * @return
     */
    public LangYaBangUserData getUserData(long userId){
        UnionActivityGroupUnion unionData = Cross2UnionActivityGroupMgr.getUnionData(activityId, userId);
        if (unionData == null) {
            return null;
        }
        LangYaBangUserData langYaUserData = userDataMap.get(userId);
        return langYaUserData;
    }

    /**
     * 初始化 客户端请求的userdata
     * @param userId
     * @param serverId
     * @param unionUid
     * @return
     */
    public LangYaBangUserData getUserData(long userId,long serverId,String unionUid) {

        boolean isNew = false;
        if (!userDataMap.containsKey(userId)) {
            synchronized (userDataMap) {
                if (!userDataMap.containsKey(userId)) {
                    LangYaBangConfig config = CrossLangYaBangConfigMgr.getConfig(activityId);
                    if (config == null) {
                        logger.error("LangYaBang Config Error ,activityId {} ,UserId{}", activityId, userId);
                        return null;
                    }
                    LangYaBangUserData tempUserData = new LangYaBangUserData();
                    tempUserData.setServerId(serverId);
                    tempUserData.setActivityId(activityId);
                    tempUserData.setGroupId(groupId);

                    Map<Integer, Integer> initBuildingMap = CrossLangYaBangConfigMgr.getInitBuildingMap(activityId);
                    if (initBuildingMap.isEmpty()) {
                        logger.error("LangYaBang Building Config Error ,activityId {} ,UserId{}", activityId, userId);
                        return null;
                    }
                    tempUserData.setBuildingLevel(initBuildingMap);
                    tempUserData.setEventIdNow(0);
                    tempUserData.setPower(config.getEnergyMaxNum());
                    tempUserData.setHistoryPower(config.getEnergyMaxNum());
                    tempUserData.setCoin(0);
                    tempUserData.setEvent(LangYaUserEvent.getNewEmptyEvent());
                    tempUserData.setLastBeenBeatTime(0);
                    tempUserData.setLastRecoveryTime(System.currentTimeMillis());
                    tempUserData.setUnionId(unionUid);
                    tempUserData.setUserId(userId);
                    tempUserData.setScore(0);
                    tempUserData.setOtherGiveRewardNum(0);
                    tempUserData.setOtherGiveReward(new Property());
                    tempUserData.setOtherGiveCoin(0);
                    tempUserData.setOtherGiveScore(0);
                    tempUserData.setHistoryCoinNum(0);
                    tempUserData.setDrawTime(CrossLangYaBangConfigMgr.getInitDrawMap(activityId));
                    tempUserData.setOpenSwitchList(new ArrayList<>());
                    tempUserData.setInsertOption();
                    isNew = true;
                    userDataMap.put(userId, tempUserData);
                }
            }
        }
        LangYaBangUserData langYaUserData = userDataMap.get(userId);
        if (isNew) {
            addUserToUnion(langYaUserData);
        }
        //玩家如果活动前换商会
        if(!Objects.equals(unionUid,langYaUserData.getUnionId())){
            //老商会
            String oldUnionId = langYaUserData.getUnionId();
            langYaUserData.setUnionId(unionUid);
            if (unionMap.containsKey(oldUnionId)){
                LangYaUnionData langYaUnionData = unionMap.get(oldUnionId);
                Set<Long> userIdSet = langYaUnionData.getUserIdSet();
                if (userIdSet.contains(userId)){
                    userIdSet.remove(userId);
                    langYaUnionData.setUpdateOption();
                }
            }
            addUserToUnion(langYaUserData);

        }
        calculatePower(userId);
        return langYaUserData;
    }

    /**
     * 将玩家加入商会信息中
     * @param tempUserData
     */

    public void addUserToUnion(LangYaBangUserData tempUserData) {
        if (StringUtils.isNullOrEmpty(tempUserData.getUnionId())) {
            logger.error("琅琊榜{}活动玩家 id:{}商会信息为空,", activityId, tempUserData.getUserId());
            return;
        }
        if (!unionMap.containsKey(tempUserData.getUnionId())) {
            synchronized (unionMap) {
                if (!unionMap.containsKey(tempUserData.getUnionId())) {

                    LangYaUnionData langYaUnionData = new LangYaUnionData();
                    langYaUnionData.setActivityId(activityId);
                    langYaUnionData.setGroupId(groupId);
                    langYaUnionData.setScoreNow(0);
                    langYaUnionData.setUnionUid(tempUserData.getUnionId());
                    Set<Long> userIdSet = new HashSet<>();
                    userIdSet.add(tempUserData.getUserId());
                    langYaUnionData.setUserIdSet(userIdSet);
                    langYaUnionData.setHateValueMap(new ConcurrentHashMap<>());
                    unionMap.put(tempUserData.getUnionId(), langYaUnionData);
                    langYaUnionData.setInsertOption();
                }
            }
        } else {
            LangYaUnionData langYaUnionData = unionMap.get(tempUserData.getUnionId());
            langYaUnionData.getUserIdSet().add(tempUserData.getUserId());
            langYaUnionData.setUpdateOption();
        }
    }

    public LangYaBangActivity(int activityId, int groupId) {
        this.activityId = activityId;
        this.groupId = groupId;
    }


    public UserBaseInfo getUserInfoById(long targetId) {
        return CrossUserMgr.getUserBaseInfo(targetId);
    }

    /**
     * 获取玩家数据 如果有pvp代政事件把对方userBaseInfo带下去
     * @param userId
     * @param userPatronsInfos
     * @param serverId
     * @return
     */

    public LangYaBangProto.LangYaBangUserDataSyncRespMsg.Builder getSyncUserData(long userId, Map<Integer, LangYaTypePatrons> userPatronsInfos,long serverId) {
        LangYaBangProto.LangYaBangUserDataSyncRespMsg.Builder reqBuilder = LangYaBangProto.LangYaBangUserDataSyncRespMsg.newBuilder();
        //活动还没开始 还没锁名单 不初始化了
        if (!CrossLangYaBangConfigMgr.checkActivityCanStart(activityId)){
            reqBuilder.setRet(GameErrorCode.E_LANG_YA_BANG_CROSS_DATA_NO_INIT);
            return reqBuilder;
        }

        UnionActivityGroupUnion unionData = Cross2UnionActivityGroupMgr.getUnionData(activityId, userId);
        if (unionData == null) {
            reqBuilder.setRet(GameErrorCode.E_LANG_YA_BANG_NO_UNION);
            return reqBuilder;
        }
        LangYaBangUserData userData = getUserData(userId,serverId,unionData.getUnionUid());
        if (userData == null) {
            reqBuilder.setRet(GameErrorCode.E_LANG_YA_BANG_CROSS_DATA_NO_INIT);
            return reqBuilder;
        }

        if (userPatronsInfos != null) {
            if (!userPatronsInfos.isEmpty()) {
                userData.setUserPatronsInfoMap(userPatronsInfos);
                reCalculateUserPatronsAbility(userData);
            }
        }
        UserBaseInfo userInfoById = null;
        int eventIdNow = userData.getEventIdNow();
        if (eventIdNow != 0) {
            LangYaRollDiceConfig diceConfigById = CrossLangYaBangConfigMgr.getDiceConfigById(activityId, eventIdNow);
            if (diceConfigById.getType() == eLangYaBangEventType.pvp.getValue() || diceConfigById.getType() == eLangYaBangEventType.daizheng.getValue()
                    || diceConfigById.getType() == eLangYaBangEventType.declareWarPvp.getValue()) {
                userInfoById = getUserInfoById(userData.getEvent().getTargetId());
            }
        }
        LangYaBangProto.LangYaBangUserDataSyncMsg.Builder userdataBuilder = LangYaBangPb.parseLangYaBangUserData(userData, userInfoById, 0L);

        reqBuilder.setRet(0);
        reqBuilder.setUserData(userdataBuilder);
        //红点提醒一下

        if (isAllDeclareWarOver(userData.getUnionId())) {
            syncUserRedDotToServer(1, 0, (int) userData.getServerId(), userId);
        } else {
            syncUserRedDotToServer(1, 1, (int) userData.getServerId(), userId);
        }
        if (isMyDeclareWarTimeOver(userData.getUnionId(), userId)) {
            syncUserRedDotToServer(2, 0, (int) userData.getServerId(), userId);
        } else {
            syncUserRedDotToServer(2, 1, (int) userData.getServerId(), userId);
        }


        //确保排行榜更新一下

        if (userData.getScore() != 0) {
            syncScoreChangeToServer(activityId, (int) userData.getServerId(), userId, userData.getScore());
        }

        return reqBuilder;
    }

    public void syncScoreChangeToServer(int activityId, int serverId, long userId, long score) {
        LangYaBangProto.LangYaBangUpdateConditionReqMsg.Builder builder = LangYaBangProto.LangYaBangUpdateConditionReqMsg.newBuilder();
        builder.setActivityId(activityId);
        builder.setServerId(serverId);
        builder.setUserId(userId);
        builder.setScore(score);
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(GameProtocol.S_LANG_YA_BANG_CROSS_SYNC_CONDITION_TO_GAME, builder);
        MessageHelper.sendPacket(serverId, userId, pbMsg);
    }

    public void syncMainDataToUser(long userId, int serverId) {
        LangYaBangProto.LangYaBangUserDataSyncRespMsg.Builder syncUserData = getSyncUserData(userId, null,serverId);
        LangYaBangProto.LangYaBangUserDataSyncMsg userData = syncUserData.getUserData();
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(ClientProtocol.U_LANG_YA_BANG_USER_MAIN_DATA_SYNC, userData);
        MessageHelper.sendPacket(serverId, userId, pbMsg);
    }

    /**
     * 判定无法进行特殊事件后 随机一个普通事件 不需要目标
     * @param buildingTotalLevel
     * @return
     */

    public int randomSimpleEvent(int buildingTotalLevel) {
        Map<Integer, Map<Integer, LangYaRollDiceConfig>> diceConfigMap = CrossLangYaBangConfigMgr.getDiceConfigMap(activityId);
        List<Integer> eventIdList = new ArrayList<>();
        List<Integer> weightList = new ArrayList<>();
        if (diceConfigMap == null){
            return 0;
        }
        for (Map.Entry<Integer, Map<Integer, LangYaRollDiceConfig>> diceConfigTypeMap : diceConfigMap.entrySet()) {
            if (diceConfigTypeMap.getKey() == eLangYaBangEventType.pvp.getValue() || diceConfigTypeMap.getKey() == eLangYaBangEventType.pve.getValue() || diceConfigTypeMap.getKey() == eLangYaBangEventType.daizheng.getValue()
                    || diceConfigTypeMap.getKey() == eLangYaBangEventType.declareWarPvp.getValue()) {
                continue;
            }

            for (LangYaRollDiceConfig diceConfig : diceConfigTypeMap.getValue().values()) {
                if (diceConfig.getUnlock() > buildingTotalLevel) {
                    continue;
                }

                eventIdList.add(diceConfig.getId());
                weightList.add(diceConfig.getWeight());
            }
        }
        int indexByWeight = RandomHelper.getRandomIndexByWeight(weightList, random);
        return eventIdList.get(indexByWeight);
    }

    /**
     * 随机所有的事件
     * @param buildingTotalLevel
     * @return
     */

    public int randomAllEventId(int buildingTotalLevel) {
        Map<Integer, Map<Integer, LangYaRollDiceConfig>> diceConfigMap = CrossLangYaBangConfigMgr.getDiceConfigMap(activityId);
        List<Integer> eventIdList = new ArrayList<>();
        List<Integer> weightList = new ArrayList<>();
        if (diceConfigMap == null){
            return 0;
        }
        for (Map<Integer, LangYaRollDiceConfig> diceConfigTypeMap : diceConfigMap.values()) {
            for (LangYaRollDiceConfig diceConfig : diceConfigTypeMap.values()) {
                if (diceConfig.getType() == eLangYaBangEventType.declareWarPvp.getValue()) {
                    continue;
                }
                if (diceConfig.getUnlock() > buildingTotalLevel) {
                    continue;
                }
                eventIdList.add(diceConfig.getId());
                weightList.add(diceConfig.getWeight());
            }
        }
        int indexByWeight = RandomHelper.getRandomIndexByWeight(weightList, random);
        return eventIdList.get(indexByWeight);

    }

    public int randomEventByType() {
        return 0;
    }

    public long getRandomEmenyUserId(long myUserId) {
        List<Long> userIds = new ArrayList<>(userDataMap.keySet());
        LangYaBangUserData userData = getUserData(myUserId);
        LangYaUnionData langYaUnionData = unionMap.get(userData.getUnionId());
        userIds.remove(myUserId);
        if (langYaUnionData != null) {
            userIds.removeAll(langYaUnionData.getUserIdSet());
        }
        if (userIds.isEmpty()) {
            return 0;
        }
        int i = random.nextInt(userIds.size());
        return userIds.get(i);
    }

    /**
     * 随机商会内成员
     * @param langYaUserData
     * @return
     */

    public long getRandomUnionUserId(LangYaBangUserData langYaUserData) {
        String unionId = langYaUserData.getUnionId();
        LangYaUnionData langYaUnionData = unionMap.get(unionId);
        if (langYaUnionData == null) {
            addUserToUnion(langYaUserData);
        }
        LangYaUnionData unionData = unionMap.get(unionId);
        List<Long> userIdList = new ArrayList<>(unionData.getUserIdSet());
        userIdList.remove(langYaUserData.getUserId());
        if (userIdList.size() == 0) {
            return 0;
        }
        int i = random.nextInt(userIdList.size());
        return userIdList.get(i);
    }

    public long getRandomAllUserId(long myUserId) {
        List<Long> userIds = new ArrayList<>(userDataMap.keySet());
        userIds.remove(myUserId);
        if (userIds.isEmpty()) {
            return 0;
        }
        int i = random.nextInt(userIds.size());
        return userIds.get(i);

    }

    /**
     * 摇骰子
     * @param userId
     * @param usePower
     * @return
     */

    public LangYaBangProto.LangYaRollDiceRespMsg.Builder rollDice(long userId, int usePower) {
        //更新体力先
        calculatePower(userId);
        LangYaBangProto.LangYaRollDiceRespMsg.Builder rollBuilder = LangYaBangProto.LangYaRollDiceRespMsg.newBuilder();
        LangYaBangUserData userData = getUserData(userId);
        synchronized (userData) {
            if (userData == null) {
                rollBuilder.setRet(GameErrorCode.E_LANG_YA_BANG_CROSS_DATA_NO_INIT);
                return rollBuilder;
            }
            if (userData.getPower() < usePower) {
                rollBuilder.setRet(GameErrorCode.E_LANG_YA_BANG_NO_POWER);
                return rollBuilder;
            }
            if (!checkCanOperateTime()) {
                rollBuilder.setRet(GameErrorCode.E_LANG_YA_BANG_NO_OPERATE_TIME);
                return rollBuilder;
            }
            if (userData.getEventIdNow() != 0) {
                rollBuilder.setRet(GameErrorCode.E_LANG_YA_EVENT_NO_END);
                return rollBuilder;
            }


            int buildingTotalLevel = CrossLangYaBangConfigMgr.getBuildingTotalLevel(activityId, userData.getBuildingLevel());
            //int maxUsePowerNum = CrossLangYaBangConfigMgr.getMaxUsePowerNum(activityId, buildingTotalLevel);
            //如果不止一倍
            if (usePower != 1) {
                //先看看有没有抽数解锁多倍
                int needDrawTime = CrossLangYaBangConfigMgr.getUsingPowerNeedDrawTime(activityId);
                if (needDrawTime == -1) {
                    rollBuilder.setRet(GameErrorCode.E_LANG_YA_BANG_CAN_NO_DRAW_THIS_POWER);
                    return rollBuilder;
                }
                //当前抽数如果小于需要的抽数 就未解锁
                if (userData.getTotalDrawTimes() < needDrawTime) {
                    rollBuilder.setRet(GameErrorCode.E_LANG_YA_BANG_CAN_NO_DRAW_THIS_POWER);
                    return rollBuilder;
                }
                //查看 使用该体力倍率需要的历史最高体力
                int usingPowerNeedHistoryPower = CrossLangYaBangConfigMgr.getUsingPowerNeedHistoryUsedPower(activityId, usePower);
                //没有这个体力类型
                if (usingPowerNeedHistoryPower == -1) {
                    rollBuilder.setRet(GameErrorCode.E_LANG_YA_BANG_CAN_NO_DRAW_THIS_POWER);
                    return rollBuilder;
                }
                if (userData.getHasAllUsedPower() < usingPowerNeedHistoryPower) {
                    rollBuilder.setRet(GameErrorCode.E_LANG_YA_BANG_CAN_NO_DRAW_THIS_POWER);
                    return rollBuilder;
                }

            }

            int eventId = 0;
            int guideId = checkGuideId(userData);
            int forceId = checkForceId(userData.getDrawTime());

            //先看有没有引导
            if (guideId != 0) {
                eventId = guideId;
            } else { //再看有没有保底
                if (forceId != 0) {
                    eventId = forceId;
                } else {     //什么都没有 再随机
                    eventId = randomAllEventId(buildingTotalLevel);
                }
            }

            LangYaRollDiceConfig diceConfigById = CrossLangYaBangConfigMgr.getDiceConfigById(activityId, eventId);
            if (diceConfigById == null) {
                rollBuilder.setRet(GameErrorCode.E_LANG_YA_BANG_CONFIG_ERROR);
                return rollBuilder;
            }

            boolean checkCanEvent = checkCanEvent(diceConfigById, userData);
            if (!checkCanEvent) {
                eventId = randomSimpleEvent(buildingTotalLevel);
                diceConfigById = CrossLangYaBangConfigMgr.getDiceConfigById(activityId, eventId);
            }
            if (diceConfigById == null) {
                logger.error(eventId + "不存在");
                rollBuilder.setRet(GameErrorCode.E_LANG_YA_BANG_CONFIG_ERROR);
                return rollBuilder;
            }
            //不管是不是报错 先扣体力
            userData.setPower(userData.getPower() - usePower);
            userData.setHasAllUsedPower(userData.getHasAllUsedPower() + usePower);
            userData.setTotalDrawTimes(userData.getTotalDrawTimes() + 1);
            int result = dealRollDiceEvent(userData, diceConfigById, rollBuilder, usePower);
            if (result != 0) {
                rollBuilder.setRet(result);
                return rollBuilder;
            }
            rollBuilder.setRet(0);
            addAndClearDrawTime(userData, eventId);
            rollBuilder.setRewardAddition(usePower);
        }
        return rollBuilder;
    }

    private void addAndClearDrawTime(LangYaBangUserData userData,int eventId){
        Map<Integer, Integer> drawTime = userData.getDrawTime();
        if (drawTime.isEmpty()){
            return;
        }
        int buildingTotalLevel = CrossLangYaBangConfigMgr.getBuildingTotalLevel(activityId, userData.getBuildingLevel());
        for (Map.Entry<Integer, Integer> entry:drawTime.entrySet()){
            LangYaRollDiceConfig diceConfigById = CrossLangYaBangConfigMgr.getDiceConfigById(activityId, entry.getKey());
            if (diceConfigById == null){
                logger.error("琅琊榜活动{},{}骰子配置不存在",activityId,entry.getKey());
                continue;
            }
            //只有解锁了才能进保底
            if (buildingTotalLevel >= diceConfigById.getUnlock()){
                entry.setValue(entry.getValue()+1);
            }
        }
        if (drawTime.containsKey(eventId)){
            drawTime.put(eventId,0);
        }
        userData.setUpdateOption();
    }

    /**
     * 引导
     * @param userData
     * @return
     */

    private int checkGuideId(LangYaBangUserData userData){
        List<Integer> guideDrawList = CrossLangYaBangConfigMgr.getGuideDrawList(activityId);
        if (guideDrawList == null){
            return 0;
        }
        if (guideDrawList.isEmpty()){
            return 0;
        }
        if (userData.getTotalDrawTimes() < guideDrawList.size()){
            return guideDrawList.get(userData.getTotalDrawTimes());
        }
        return 0;
    }

    /**
     * 保底
     * @param drawMap
     * @return
     */

    private int checkForceId(Map<Integer,Integer> drawMap){
        if (drawMap.isEmpty()){
            return 0;
        }
        Map<Integer,LangYaRollDiceConfig> diceConfigMap = new ConcurrentHashMap<>();
        for (Map.Entry<Integer,Integer> entry:drawMap.entrySet()){
            LangYaRollDiceConfig diceConfigById = CrossLangYaBangConfigMgr.getDiceConfigById(activityId, entry.getKey());
            if (diceConfigById == null){
                logger.error("活动id{}的骰子配置{}不存在",activityId,entry.getKey());
                continue;
            }
            if (entry.getValue() >= diceConfigById.getProtectNum()){
                diceConfigMap.put(diceConfigById.getType(),diceConfigById);
            }
        }
        if (diceConfigMap.isEmpty()){
            return 0;
        }
        if (diceConfigMap.containsKey(eLangYaBangEventType.pvp.getValue())){
            return diceConfigMap.get(eLangYaBangEventType.pvp.getValue()).getId();
        }
        if (diceConfigMap.containsKey(eLangYaBangEventType.pve.getValue())){
            return diceConfigMap.get(eLangYaBangEventType.pve.getValue()).getId();
        }
        if (diceConfigMap.containsKey(eLangYaBangEventType.daizheng.getValue())){
            return diceConfigMap.get(eLangYaBangEventType.daizheng.getValue()).getId();
        }
        if (diceConfigMap.containsKey(eLangYaBangEventType.power.getValue())){
            return diceConfigMap.get(eLangYaBangEventType.power.getValue()).getId();
        }
        if (diceConfigMap.containsKey(eLangYaBangEventType.AllBigCoin.getValue())){
            return diceConfigMap.get(eLangYaBangEventType.AllBigCoin.getValue()).getId();
        }
        if (diceConfigMap.containsKey(eLangYaBangEventType.AllCoin.getValue())){
            return diceConfigMap.get(eLangYaBangEventType.AllCoin.getValue()).getId();
        }
        if (diceConfigMap.containsKey(eLangYaBangEventType.Mix.getValue())){
            return diceConfigMap.get(eLangYaBangEventType.Mix.getValue()).getId();
        }
        return 0;
    }

    private void calculatePower(long userId) {
        LangYaBangUserData userData = getUserData(userId);
        if (userData == null) {
            return;
        }
        LangYaBangConfig config = CrossLangYaBangConfigMgr.getConfig(activityId);
        long now = System.currentTimeMillis();
        if (!DateHelper.isSameDay((userData.getLastRecoveryTime()/1000),(now /1000))){
            if (userData.getPower() < config.getEnergyMaxNum()){
                userData.setPower(config.getEnergyMaxNum());
            }
            userData.setLastRecoveryTime(now);
            return;
        }

        CalcPowerResult calcPowerResult = PowerHelper.calcPower(userData.getLastRecoveryTime() / 1000, config.getEnergyRecoveryCd(), config.getEnergyRecoveryPerTime(), config.getEnergyMaxNum(), userData.getPower());
        userData.setPower(calcPowerResult.getCurPower());
        userData.setLastRecoveryTime(calcPowerResult.getLastRecoverTime() * 1000);
    }

    /**
     * 处理各种事件
     * @param userData
     * @param config
     * @param rollBuilder
     * @param usePower
     * @return
     */

    private int dealRollDiceEvent(LangYaBangUserData userData, LangYaRollDiceConfig config, LangYaBangProto.LangYaRollDiceRespMsg.Builder rollBuilder, int usePower) {
        UserBaseInfo userBaseInfo = null;

        long oldCoin = userData.getCoin();
        if (config.getType() == eLangYaBangEventType.AllCoin.getValue()) {
            int coinAddition = 0;
            List<Integer> buildingAddition = CrossLangYaBangConfigMgr.getBuildingTypeAddition(activityId, eLangYaBangBuildingBuffType.drawCoinAdd.getValue(), userData.getBuildingLevel());
            if (buildingAddition != null) {
                coinAddition += buildingAddition.get(0);
            }
            //int buildingTotalLevelCoinAddition = CrossLangYaBangConfigMgr.getBuildingTotalLevelCoinAddition(activityId, userData.getBuildingLevel());
            int baseCoinNum = config.getBaseProduceList().get(0);

//            long resultCoin = BigDecimal.valueOf(buildingTotalLevelCoinAddition)
//                    .divide(BigDecimal.valueOf(1000), 2, BigDecimal.ROUND_UP)

            long resultCoin = BigDecimal.valueOf(baseCoinNum)
                    .multiply(BigDecimal.valueOf(1).add(BigDecimal.valueOf(coinAddition)
                            .divide(BigDecimal.valueOf(1000), 2, BigDecimal.ROUND_UP)))
                    .setScale(0, RoundingMode.UP).longValue();

            long l = resultCoin * usePower;

            userData.setCoin(oldCoin + l);
            userData.setHistoryCoinNum(userData.getHistoryCoinNum()+l);
            rollBuilder.setCoinReward(resultCoin);
            LogLangYaBangDraw logLangYaBangDraw = new LogLangYaBangDraw(activityId,userData.getUserId(),userData.getPower()+usePower,usePower,userData.getPower(),config.getId(),"",oldCoin,l,userData.getCoin(), JSON.toJSONString(userData.getBuildingLevel()),new Date());
            LogCrossLangYaBang.addLogLangYaBangDraw(logLangYaBangDraw);
        } else if (config.getType() == eLangYaBangEventType.AllBigCoin.getValue()) {
            int coinAddition = 0;
            List<Integer> buildingAddition = CrossLangYaBangConfigMgr.getBuildingTypeAddition(activityId, eLangYaBangBuildingBuffType.drawCoinAdd.getValue(), userData.getBuildingLevel());
            if (buildingAddition != null) {
                coinAddition += buildingAddition.get(0);
            }
            //int buildingTotalLevelCoinAddition = CrossLangYaBangConfigMgr.getBuildingTotalLevelCoinAddition(activityId, userData.getBuildingLevel());

            int coinNum = config.getBaseProduceList().get(0);

            long resultCoin = BigDecimal.valueOf(coinNum)
                    .multiply(BigDecimal.valueOf(1).add(BigDecimal.valueOf(coinAddition)
                            .divide(BigDecimal.valueOf(1000), 2, BigDecimal.ROUND_UP)))
                    .setScale(0, RoundingMode.UP).longValue();

            long l = resultCoin * usePower;

            userData.setCoin(oldCoin + l);
            userData.setHistoryCoinNum(userData.getHistoryCoinNum()+l);
            rollBuilder.setHighCoinReward(resultCoin);
            LogLangYaBangDraw logLangYaBangDraw = new LogLangYaBangDraw(activityId,userData.getUserId(),userData.getPower()+usePower,usePower,userData.getPower(),config.getId(),"",oldCoin,l,userData.getCoin(),JSON.toJSONString(userData.getBuildingLevel()),new Date());
            LogCrossLangYaBang.addLogLangYaBangDraw(logLangYaBangDraw);
        } else if (config.getType() == eLangYaBangEventType.AllInspiration.getValue()) {
            Property property = PropertyHelper.parseStringToProperty(config.getReward());
            BigInteger countByGoodsId = property.getCountByGoodsId(CrossLangYaBangConfigMgr.getConfig(activityId).getInspirationItemId());
            rollBuilder.setInspirationReward(countByGoodsId.intValue());
            LogLangYaBangDraw logLangYaBangDraw = new LogLangYaBangDraw(activityId,userData.getUserId(),userData.getPower()+usePower,usePower,userData.getPower(),config.getId(),PropertyHelper.parsePropertyToString(property),oldCoin,0,userData.getCoin(),JSON.toJSONString(userData.getBuildingLevel()),new Date());
            LogCrossLangYaBang.addLogLangYaBangDraw(logLangYaBangDraw);

        } else if (config.getType() == eLangYaBangEventType.Mix.getValue()) {
            int coinAddition = 0;
            List<Integer> buildingAddition = CrossLangYaBangConfigMgr.getBuildingTypeAddition(activityId, eLangYaBangBuildingBuffType.drawCoinAdd.getValue(), userData.getBuildingLevel());
            if (buildingAddition != null) {
                coinAddition += buildingAddition.get(0);
            }
            //int buildingTotalLevelCoinAddition = CrossLangYaBangConfigMgr.getBuildingTotalLevelCoinAddition(activityId, userData.getBuildingLevel());
            int coinNum = config.getBaseProduceList().get(0);
            long resultCoinNum =BigDecimal.valueOf(coinNum)
                    .multiply(BigDecimal.valueOf(1).add(BigDecimal.valueOf(coinAddition)
                            .divide(BigDecimal.valueOf(1000), 2, BigDecimal.ROUND_UP)))
                    .setScale(0, RoundingMode.UP).longValue();

            int highCoinNum = config.getBaseProduceList().get(1);
            long resultHighCoinNum = BigDecimal.valueOf(highCoinNum)
                    .multiply(BigDecimal.valueOf(1).add(BigDecimal.valueOf(coinAddition)
                            .divide(BigDecimal.valueOf(1000), 2, BigDecimal.ROUND_UP)))
                    .setScale(0, RoundingMode.UP).longValue();


            long trueCoin = (resultCoinNum + resultHighCoinNum) * usePower;
            userData.setCoin(oldCoin + trueCoin);
            userData.setHistoryCoinNum(userData.getHistoryCoinNum()+trueCoin);

            Property property = PropertyHelper.parseStringToProperty(config.getReward());
            BigInteger countByGoodsId = property.getCountByGoodsId(CrossLangYaBangConfigMgr.getConfig(activityId).getInspirationItemId());
            rollBuilder.setInspirationReward(countByGoodsId.intValue());

            rollBuilder.setCoinReward(resultCoinNum);
            rollBuilder.setHighCoinReward(resultHighCoinNum);

            LogLangYaBangDraw logLangYaBangDraw = new LogLangYaBangDraw(activityId,userData.getUserId(),userData.getPower()+usePower,usePower,userData.getPower(),config.getId(),config.getReward(),oldCoin,trueCoin,userData.getCoin(),JSON.toJSONString(userData.getBuildingLevel()),new Date());
            LogCrossLangYaBang.addLogLangYaBangDraw(logLangYaBangDraw);
        } else if (config.getType() == eLangYaBangEventType.power.getValue()) {
            List<Integer> buildingTypeAddition = CrossLangYaBangConfigMgr.getBuildingTypeAddition(activityId, eLangYaBangBuildingBuffType.powerAdd.getValue(), userData.getBuildingLevel());
            int power = PropertyHelper.parseStringToProperty(config.getReward()).getCountByGoodsId(CrossLangYaBangConfigMgr.getConfig(activityId).getPowerSelfId()).intValue();

            int rate = 0;
            if (buildingTypeAddition != null) {
                rate = buildingTypeAddition.get(0);
            }
            int i = random.nextInt(1000);
            if (i < rate) {
                power = BigDecimal.valueOf(power).multiply(BigDecimal.valueOf(1000 + buildingTypeAddition.get(1))).divide(BigDecimal.valueOf(1000), 0, RoundingMode.UP).intValue();
            }

            int oldPower = userData.getPower();
            userData.setPower(oldPower + power * usePower);
            if (userData.getPower() > userData.getHistoryPower()){
                userData.setHistoryPower(userData.getPower());
            }
            rollBuilder.setPowerReward(power);

            LogLangYaBangDraw logLangYaBangDraw = new LogLangYaBangDraw(activityId,userData.getUserId(),oldPower+usePower,usePower,userData.getPower(),config.getId(),config.getReward(),oldCoin,0,userData.getCoin(),JSON.toJSONString(userData.getBuildingLevel()),new Date());
            LogCrossLangYaBang.addLogLangYaBangDraw(logLangYaBangDraw);


        } else if (config.getType() == eLangYaBangEventType.clue.getValue()) {
            int buildingAdd = 0;
//            List<Integer> buildingTypeAddition = CrossLangYaBangConfigMgr.getBuildingTypeAddition(activityId, eLangYaBangBuildingBuffType.clueAdd.getValue(), userData.getBuildingLevel());
            List<Integer> buildingTypeAddition = new ArrayList<>();
            buildingTypeAddition.add(0);
            if (buildingTypeAddition != null) {
                buildingAdd = buildingTypeAddition.get(0);
            }
            Property property = PropertyHelper.parseStringToProperty(config.getReward());

            BigInteger countByGoodsId = property.getCountByGoodsId(CrossLangYaBangConfigMgr.getConfig(activityId).getCaseClueItemId());
            int goodNum = BigDecimal.valueOf(usePower).multiply(BigDecimal.valueOf(1).add(BigDecimal.valueOf(buildingAdd).divide(BigDecimal.valueOf(1000), 1, RoundingMode.UP))).multiply(BigDecimal.valueOf(countByGoodsId.intValue())).intValue();
            property.setGood(CrossLangYaBangConfigMgr.getConfig(activityId).getCaseClueItemId(), BigInteger.valueOf(goodNum));
            rollBuilder.setCaseItemReward(goodNum);

            LogLangYaBangDraw logLangYaBangDraw = new LogLangYaBangDraw(activityId,userData.getUserId(),userData.getPower()+usePower,usePower,userData.getPower(),config.getId(),config.getReward(),oldCoin,0,userData.getCoin(),JSON.toJSONString(userData.getBuildingLevel()),new Date());
            LogCrossLangYaBang.addLogLangYaBangDraw(logLangYaBangDraw);

        } else if (config.getType() == eLangYaBangEventType.daizheng.getValue()) {
            userData.setEventIdNow(config.getId());

            long randomUnionUserId = getRandomUnionUserId(userData);
            LangYaBangUserData unionMemberUserData = userDataMap.get(randomUnionUserId);

            LangYaUserEvent event = userData.getEvent();

            userBaseInfo = CrossUserMgr.getUserBaseInfo(randomUnionUserId);

            Map<Integer, LangYaUserBuilding> daiZhengBuildingData = getDaiZhengBuildingData(unionMemberUserData.getBuildingLevel(), config.getEventParamList().get(1));
            event.setPvpWinTime(0);
            event.setTargetId(randomUnionUserId);
            event.setTargetBuilding(daiZhengBuildingData);
            event.setAddition(usePower);
            event.setRemainOperateTime(config.getEventParamList().get(0));
            userData.setUpdateOption();

            LogLangYaBangDraw logLangYaBangDraw = new LogLangYaBangDraw(activityId,userData.getUserId(),userData.getPower()+usePower,usePower,userData.getPower(),config.getId(),"",oldCoin,0,userData.getCoin(),JSON.toJSONString(userData.getBuildingLevel()),new Date());
            LogCrossLangYaBang.addLogLangYaBangDraw(logLangYaBangDraw);
        } else if (config.getType() == eLangYaBangEventType.pve.getValue()) {
            //拿pve的人
            LangYaBangPveConfig randomPveConfig = CrossLangYaBangConfigMgr.getRandomPveConfig(activityId);
            if (randomPveConfig == null){
                userData.setEventIdNow(0);
                //返还体力
                userData.setPower(userData.getPower()+usePower);
                logger.error("琅琊榜活动{} 玩家{} npc配置取不到 ",activityId,userData.getUserId());
                return GameErrorCode.E_LANG_YA_BANG_CONFIG_ERROR;
            }
            //随机一下点击次数
            int canBattleTime = CrossLangYaBangConfigMgr.getRandomAttackTime(activityId);

            userData.setEventIdNow(config.getId());
            LangYaUserEvent event = userData.getEvent();
            event.setTargetId(randomPveConfig.getNpcId());
            event.setNpcAllBlood(randomPveConfig.getBaseCoin());
            event.setNpcHasRobBlood(0);
            event.setMaxNpcAttackTime(canBattleTime);

            event.setRemainOperateTime(canBattleTime);
            event.setAddition(usePower);
            LogLangYaBangDraw logLangYaBangDraw = new LogLangYaBangDraw(activityId,userData.getUserId(),userData.getPower()+usePower,usePower,userData.getPower(),config.getId(),"",oldCoin,0,userData.getCoin(),JSON.toJSONString(userData.getBuildingLevel()),new Date());
            LogCrossLangYaBang.addLogLangYaBangDraw(logLangYaBangDraw);

        } else if (config.getType() == eLangYaBangEventType.pvp.getValue()) {

            long randomEnemyUserId = getRandomPvpUserByRank(userData);
            //保险 如果进来里面但是拿不到id了
            if (randomEnemyUserId == 0){
                userData.setPower(userData.getPower()+usePower);
                userData.setEventIdNow(0);
                logger.error("琅琊榜活动{}玩家{}取可攻击玩家时没有玩家 返还体力 ",activityId,userData.getUserId());
                return GameErrorCode.E_LANG_YA_BANG_EVENT_DATA_ERROR;
            }
            userData.setEventIdNow(config.getId());
            LangYaBangUserData enemyUserData = userDataMap.get(randomEnemyUserId);
            enemyUserData.setLastBeenBeatTime(System.currentTimeMillis());
            LangYaUserEvent event = userData.getEvent();
            event.setTargetId(randomEnemyUserId);
            event.setPvpWinTime(0);
            event.setRemainOperateTime(5);
            int randomType = random.nextInt(5) + 1;
            event.setBattlePatronType(randomType);

            userBaseInfo = CrossUserMgr.getUserBaseInfo(randomEnemyUserId);

            event.setTargetBuilding(getPvpEnemyBuildingData(enemyUserData.getBuildingLevel()));
            event.setTargetPatrons(new ConcurrentHashMap<>(enemyUserData.getUserPatronsInfoMap()));
            event.setAddition(usePower);

            userData.setUpdateOption();
            LogLangYaBangDraw logLangYaBangDraw = new LogLangYaBangDraw(activityId,userData.getUserId(),userData.getPower()+usePower,usePower,userData.getPower(),config.getId(),"",oldCoin,0,userData.getCoin(),JSON.toJSONString(userData.getBuildingLevel()),new Date());
            LogCrossLangYaBang.addLogLangYaBangDraw(logLangYaBangDraw);
        }
        LangYaUnionData langYaUnionData = unionMap.get(userData.getUnionId());
        rollBuilder.setRet(0);
        rollBuilder.setDiceEventId(config.getId());
        rollBuilder.setUserData(LangYaBangPb.parseLangYaBangUserData(userData, userBaseInfo, langYaUnionData.getScoreNow()));
        return 0;
    }

    public int getTotalLevel(LangYaBangUserData userData) {
        Map<Integer, Integer> buildingLevel = userData.getBuildingLevel();
        int totalLevel = 0;
        for (Map.Entry<Integer, Integer> entry : buildingLevel.entrySet()) {
            LangYaBangAreaConfig langYaBangAreaConfig = CrossLangYaBangConfigMgr.getLangYaBangAreaConfig(activityId, entry.getKey(), entry.getValue());
            totalLevel += langYaBangAreaConfig.getLv();
        }
        return totalLevel;

    }

    private boolean checkCanEvent(LangYaRollDiceConfig diceConfigById, LangYaBangUserData userData) {
        if (eLangYaBangEventType.pvp.getValue() == diceConfigById.getType()) {
            long randomEmenyUserId = getRandomPvpUserByRank(userData);
            if (randomEmenyUserId == 0) {
                return false;
            }
            return true;
        }

        if (eLangYaBangEventType.daizheng.getValue() == diceConfigById.getType()) {
            long randomUnionUserId = getRandomUnionUserId(userData);
            if (randomUnionUserId == 0) {
                return false;
            }
            return true;
        }

        return true;
    }

    private Map<Integer, LangYaUserBuilding> getPvpEnemyBuildingData(Map<Integer, Integer> userBuildingMap) {
        Map<Integer, LangYaUserBuilding> buildingMap = new ConcurrentHashMap<>();
        for (Map.Entry<Integer, Integer> entry : userBuildingMap.entrySet()) {
            LangYaUserBuilding langYaUserBuilding = new LangYaUserBuilding();
            langYaUserBuilding.setBuildingId(entry.getKey());
            langYaUserBuilding.setLevelId(entry.getValue());
            langYaUserBuilding.setIsSuccess(0);
            langYaUserBuilding.setOperateStatus(0);
            buildingMap.put(entry.getKey(), langYaUserBuilding);
        }
        return buildingMap;

    }

    private Map<Integer, LangYaUserBuilding> getDaiZhengBuildingData(Map<Integer, Integer> userBuildingMap, int successNum) {
        Map<Integer, LangYaUserBuilding> buildingMap = new ConcurrentHashMap<>();

        for (Map.Entry<Integer, Integer> entry : userBuildingMap.entrySet()) {
            LangYaUserBuilding langYaUserBuilding = new LangYaUserBuilding();
            langYaUserBuilding.setBuildingId(entry.getKey());
            langYaUserBuilding.setLevelId(entry.getValue());
            langYaUserBuilding.setOperateStatus(0);
            langYaUserBuilding.setIsSuccess(0);
            buildingMap.put(entry.getKey(), langYaUserBuilding);
        }
        List<Integer> list = new ArrayList<>(buildingMap.keySet());
        List<Integer> differentRandomNum = RandomHelper.getDifferentRandomNum(list.size(), successNum);
        for (int index : differentRandomNum) {
            buildingMap.get(list.get(index)).setIsSuccess(1);
        }
        return buildingMap;
    }


    public LangYaBangProto.DoDaizhengEventRespMsg.Builder daiZheng(long userId, int chooseBuilding) {
        LangYaBangProto.DoDaizhengEventRespMsg.Builder builder = LangYaBangProto.DoDaizhengEventRespMsg.newBuilder();
        LangYaBangUserData userData = getUserData(userId);
        synchronized (userData) {
            int eventIdNow = userData.getEventIdNow();
            LangYaRollDiceConfig diceConfigById = CrossLangYaBangConfigMgr.getDiceConfigById(activityId, eventIdNow);
            if (diceConfigById == null) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_CONFIG_ERROR);
                return builder;
            }
            if (diceConfigById.getType() != eLangYaBangEventType.daizheng.getValue()) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_CONFIG_ERROR);
                return builder;
            }
            if (!checkCanOperateTime()) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_NO_OPERATE_TIME);
                return builder;
            }
            LangYaUserEvent event = userData.getEvent();
            if (event.getTargetId() == 0) {      //有误
                userData.setEventIdNow(0);
                userData.setEvent(LangYaUserEvent.getNewEmptyEvent());
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_EVENT_DATA_ERROR);
                return builder;
            }
            if (event.getTargetBuilding() == null || event.getTargetBuilding().isEmpty()) {
                userData.setEventIdNow(0);
                userData.setEvent(LangYaUserEvent.getNewEmptyEvent());
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_EVENT_DATA_ERROR);
                return builder;
            }
            Map<Integer, LangYaUserBuilding> targetBuildingMap = event.getTargetBuilding();

            LangYaUserBuilding chooseBuildingData = targetBuildingMap.get(chooseBuilding);
            if (chooseBuildingData == null) {
                userData.setEventIdNow(0);
                userData.setEvent(LangYaUserEvent.getNewEmptyEvent());
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_EVENT_DATA_ERROR);
                return builder;
            }
            if (chooseBuildingData.getOperateStatus() == 1) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_DAI_ZHENG_HAS_OPERATE);
                return builder;
            }
            int powerAdd = event.getAddition();
            int isOver = 0;
            event.setRemainOperateTime(event.getRemainOperateTime() - 1);

            chooseBuildingData.setOperateStatus(1);
            if (chooseBuildingData.getIsSuccess() == 1) {
                String reward = diceConfigById.getReward();
                if (!StringUtils.isNullOrEmpty(reward)) {
                    if (!reward.equals("0")) {
                        List<String> strings = StringUtils.stringToStringList(reward, "@");
                        Property randomReward = PropertyHelper.parseNewStringToProperty(strings.get(event.getPvpWinTime()));
                        if (event.getTemporaryReward() == null) {
                            event.setTemporaryReward(new Property());
                        }
                        event.getTemporaryReward().addProperty(randomReward);
                    }
                }

                event.setPvpWinTime(event.getPvpWinTime() + 1);

                builder.setDaizhengSuccess(1);
            } else {
                builder.setDaizhengSuccess(0);
            }
            if (event.getRemainOperateTime() <= 0) {
                isOver = 1;
            }
            builder.setRet(0);
            UserBaseInfo userBaseInfo = null;
            if (isOver == 1) {
                Map<Integer, Integer> levelMap = new ConcurrentHashMap<>();
                for (Map.Entry<Integer, LangYaUserBuilding> entry : targetBuildingMap.entrySet()) {
                    levelMap.put(entry.getKey(), entry.getValue().getLevelId());
                }

                //int buildingTotalLevelCoinAddition = CrossLangYaBangConfigMgr.getBuildingTotalLevelCoinAddition(activityId, userData.getBuildingLevel());
                List<Integer> buildingTypeAddition = CrossLangYaBangConfigMgr.getBuildingTypeAddition(activityId, eLangYaBangBuildingBuffType.daiZhengCoinAdd.getValue(), userData.getBuildingLevel());
                List<Integer> otherBuildingTypeAddition = CrossLangYaBangConfigMgr.getBuildingTypeAddition(activityId, eLangYaBangBuildingBuffType.daiZhengCoinAdd.getValue(), levelMap);

                long coinReward = 0;
                for (int i = 0; i < event.getPvpWinTime(); i++) {
                    coinReward += diceConfigById.getBaseProduceList().get(i);
                }


                BigDecimal buildingAreaAdd = BigDecimal.valueOf(1).add(BigDecimal.valueOf(buildingTypeAddition.get(0)).divide(BigDecimal.valueOf(1000), 2, RoundingMode.UP));
                BigDecimal otherBuildingAreaAdd = BigDecimal.valueOf(1).add(BigDecimal.valueOf(otherBuildingTypeAddition.get(0)).divide(BigDecimal.valueOf(1000), 2, RoundingMode.UP));
                //BigDecimal totalBuildingLevelAdd = BigDecimal.valueOf(buildingTotalLevelCoinAddition).divide(BigDecimal.valueOf(1000), 2, RoundingMode.UP);

                builder.setOriginCoin(coinReward);
                builder.addCalculateParam(buildingAreaAdd.doubleValue());
                //builder.addCalculateParam(totalBuildingLevelAdd.doubleValue());
                builder.addCalculateParam(otherBuildingAreaAdd.doubleValue());

                long resultCoin = BigDecimal.valueOf(coinReward)
                        .multiply(buildingAreaAdd).setScale(2, RoundingMode.UP)
                        .multiply(otherBuildingAreaAdd).setScale(2, RoundingMode.UP)

                        .setScale(0, RoundingMode.UP)
                        .longValue();

                Property temporaryReward = event.getTemporaryReward();
//  给别人奖励          20230510 智坤说不给别人奖励了
//            LangYaBangUserData daiZhengTarget = userDataMap.get(event.getTargetId());
//            if (!temporaryReward.isNothing()) {
//                long otherResultCoin = BigDecimal.valueOf(powerAdd).multiply(BigDecimal.valueOf(resultCoin).multiply(BigDecimal.valueOf(diceConfigById.getEventParamList().get(2))).divide(BigDecimal.valueOf(1000),1,RoundingMode.UP)).longValue();
//                daiZhengTarget.setOtherGiveCoin(daiZhengTarget.getOtherGiveCoin()+otherResultCoin);
//                daiZhengTarget.setOtherGiveRewardNum(daiZhengTarget.getOtherGiveRewardNum() + 1);
//                daiZhengTarget.getOtherGiveReward().addProperty(event.getTemporaryReward());
//            }
//            UserBaseInfo targetBaseInfo = CrossUserMgr.getUserBaseInfo(event.getTargetId());
//            if (targetBaseInfo != null) {
//                syncMainDataToUser(event.getTargetId(), (int) targetBaseInfo.getServerId());
//            }

                long trueCoin = powerAdd * resultCoin;
                long oldCoin = userData.getCoin();
                userData.setCoin(oldCoin + trueCoin);
                userData.setHistoryCoinNum(userData.getHistoryCoinNum() + trueCoin);

                builder.setIsOver(1);

                builder.setResultReward(PropertyHelper.parsePropertyToString(temporaryReward));
                userData.setEventIdNow(0);
                builder.setNowEvent(0);
                userBaseInfo = CrossUserMgr.getUserBaseInfo(userData.getEvent().getTargetId());
                builder.setGameEventData(LangYaBangPb.parseLangYaBangUserEventData(userData.getEvent(), userBaseInfo));
                userData.setEvent(LangYaUserEvent.getNewEmptyEvent());
                builder.setCoinReward(resultCoin);
                builder.setRewardPowerAddition(powerAdd);
                builder.setUserData(LangYaBangPb.parseLangYaBangUserData(userData, null, 0));
                temporaryReward.goodCountMultiNum(powerAdd);
                LogLangYaBangDaiZheng logLangYaBangDaiZheng = new LogLangYaBangDaiZheng(activityId, userId, event.getTargetId(), JSON.toJSONString(targetBuildingMap), JSON.toJSONString(userData.getBuildingLevel()), event.getAddition(), PropertyHelper.parsePropertyToString(temporaryReward), oldCoin, trueCoin, userData.getCoin(), new Date());
                LogCrossLangYaBang.addLogLangYaBangDaiZheng(logLangYaBangDaiZheng);

            } else {
                builder.setIsOver(0);
                builder.setNowEvent(userData.getEventIdNow());
                builder.setRewardPowerAddition(powerAdd);
                userBaseInfo = CrossUserMgr.getUserBaseInfo(userData.getEvent().getTargetId());
                builder.setGameEventData(LangYaBangPb.parseLangYaBangUserEventData(userData.getEvent(), userBaseInfo));
            }
        }
        return builder;
    }

    public LangYaBangProto.DoPveEventRespMsg.Builder dealPve(long userId) {
        LangYaBangProto.DoPveEventRespMsg.Builder builder = LangYaBangProto.DoPveEventRespMsg.newBuilder();
        LangYaBangUserData userData = getUserData(userId);
        synchronized (userData) {
            int eventIdNow = userData.getEventIdNow();
            if (eventIdNow == 0) {
                System.out.println("event id 0");
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_EVENT_DATA_ERROR);
                return builder;
            }
            LangYaRollDiceConfig diceConfigById = CrossLangYaBangConfigMgr.getDiceConfigById(activityId, eventIdNow);
            if (!checkCanOperateTime()) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_NO_OPERATE_TIME);
                return builder;
            }
            if (diceConfigById == null) {
                System.out.println("config error");
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_CONFIG_ERROR);
                return builder;
            }

            LangYaUserEvent event = userData.getEvent();
            int remainOperateTime = event.getRemainOperateTime();
            if (remainOperateTime <= 0) {
                System.out.println("no times");
                userData.setEventIdNow(0);
                userData.setEvent(LangYaUserEvent.getNewEmptyEvent());
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_EVENT_DATA_ERROR);
                return builder;
            }
            //拿配置
            LangYaBangPveConfig langYaBangPveConfig = CrossLangYaBangConfigMgr.getConfig(activityId).getPveConfigMap().get((int) event.getTargetId());
            if (langYaBangPveConfig == null) {
                System.out.println("no config");
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_CONFIG_ERROR);
                return builder;
            }
            builder.setRet(0);
            event.setRemainOperateTime(event.getRemainOperateTime() - 1);
            //这下打的伤害千分比
            int damageRate = CrossLangYaBangConfigMgr.getRandomLoseBlood(activityId);
            builder.setLoseBloodRate(damageRate);
            //算实际伤害
            long damageNum = BigDecimal.valueOf(event.getNpcAllBlood()).multiply(BigDecimal.valueOf(damageRate)).divide(BigDecimal.valueOf(1000), 0, RoundingMode.UP).longValue();
            //先加伤害
            if ((event.getNpcHasRobBlood() + damageNum) >= event.getNpcAllBlood()) {
                event.setNpcHasRobBlood(event.getNpcAllBlood());
            } else {
                event.setNpcHasRobBlood(event.getNpcHasRobBlood() + damageNum);
            }
            //先判断是不是结束了    没操作次数或打的血量满了
            if (event.getRemainOperateTime() <= 0 || event.getNpcHasRobBlood() >= event.getNpcAllBlood()) {
                builder.setIsEventOver(1);
                builder.setRewardPowerAddition(event.getAddition());
                userData.setEventIdNow(0);
                String reward = langYaBangPveConfig.getReward();
                List<String> strings = new ArrayList<>();
                if (!StringUtils.isNullOrEmpty(reward) && !reward.equals("0")) {
                    strings = StringUtils.stringToStringList(reward, "@");
                }


                //建筑加成
                //int buildingTotalLevelCoinAddition = CrossLangYaBangConfigMgr.getBuildingTotalLevelCoinAddition(activityId, userData.getBuildingLevel());
                List<Integer> buildingTypeAddition = CrossLangYaBangConfigMgr.getBuildingTypeAddition(activityId, eLangYaBangBuildingBuffType.pveCoinAdd.getValue(), userData.getBuildingLevel());

                //BigDecimal buildingTotalAdd = BigDecimal.valueOf(buildingTotalLevelCoinAddition).divide(BigDecimal.valueOf(1000), 2, RoundingMode.UP);
                BigDecimal areaAdd = BigDecimal.valueOf(1).add(BigDecimal.valueOf(buildingTypeAddition.get(0)).divide(BigDecimal.valueOf(1000), 2, RoundingMode.UP));

                builder.addCalculateParam(areaAdd.doubleValue());
//            builder.addCalculateParam(buildingTotalAdd.doubleValue());
                //如果打不满
                if (event.getNpcHasRobBlood() < event.getNpcAllBlood()) {
                    Property property = new Property();
                    if (!strings.isEmpty()) {
                        property = PropertyHelper.parseNewStringToProperty(strings.get(0));
                    }

                    builder.setFinalReward(PropertyHelper.parsePropertyToString(property));
                    property.goodCountMultiNum(event.getAddition());


                    long coinReward = event.getNpcHasRobBlood();
                    builder.setOriginCoin(coinReward);

                    long resultCoin = BigDecimal.valueOf(coinReward)
                            .multiply(areaAdd).setScale(2, RoundingMode.UP)
//                        .multiply(buildingTotalAdd).setScale(2, RoundingMode.UP)
                            .setScale(0, RoundingMode.UP)
                            .longValue();

                    long trueCoin = resultCoin * event.getAddition();
                    long oldCoin = userData.getCoin();
                    userData.setCoin(oldCoin + trueCoin);
                    userData.setHistoryCoinNum(userData.getHistoryCoinNum() + trueCoin);

                    builder.setFinalRewardCoin(resultCoin);
                    builder.setGameEventData(LangYaBangPb.parseLangYaBangUserEventData(event, null));
                    userData.setEvent(LangYaUserEvent.getNewEmptyEvent());
                    builder.setUserData(LangYaBangPb.parseLangYaBangUserData(userData, null, 0));
                    LogLangYaBangPve logLangYaBangPve = new LogLangYaBangPve(activityId, userId, langYaBangPveConfig.getNpcId(), event.getMaxNpcAttackTime(), event.getRemainOperateTime(), event.getNpcHasRobBlood(), PropertyHelper.parsePropertyToString(property), event.getAddition(), oldCoin, trueCoin, userData.getCoin(), JSON.toJSONString(userData.getBuildingLevel()), new Date());
                    LogCrossLangYaBang.addLogLangYaBangPve(logLangYaBangPve);

                    return builder;
                } else {  //打满了 有额外奖励

                    Property property = new Property();
                    if (!strings.isEmpty()) {
                        property = PropertyHelper.parseNewStringToProperty(strings.get(1));
                    }

                    builder.setFinalReward(PropertyHelper.parsePropertyToString(property));
                    property.goodCountMultiNum(event.getAddition());

                    BigDecimal exAdd = (BigDecimal.valueOf(1000 + langYaBangPveConfig.getExCoin())).divide(BigDecimal.valueOf(1000), 2, RoundingMode.UP);
                    builder.addCalculateParam(exAdd.doubleValue());

                    long coinReward = event.getNpcAllBlood();
                    builder.setOriginCoin(coinReward);
                    long resultCoin = BigDecimal.valueOf(coinReward)
                            .multiply(areaAdd).setScale(2, RoundingMode.UP)
                            //.multiply(buildingTotalAdd).setScale(2, RoundingMode.UP)
                            .multiply(exAdd)
                            .setScale(0, RoundingMode.UP)
                            .longValue();
                    long trueCoin = resultCoin * event.getAddition();
                    long oldCoin = userData.getCoin();
                    userData.setCoin(oldCoin + trueCoin);
                    userData.setHistoryCoinNum(userData.getHistoryCoinNum() + trueCoin);

                    builder.setFinalRewardCoin(resultCoin);
                    builder.setGameEventData(LangYaBangPb.parseLangYaBangUserEventData(event, null));
                    userData.setEvent(LangYaUserEvent.getNewEmptyEvent());
                    builder.setUserData(LangYaBangPb.parseLangYaBangUserData(userData, null, 0));

                    LogLangYaBangPve logLangYaBangPve = new LogLangYaBangPve(activityId, userId, langYaBangPveConfig.getNpcId(), event.getMaxNpcAttackTime(), event.getRemainOperateTime(), event.getNpcHasRobBlood(), PropertyHelper.parsePropertyToString(property), event.getAddition(), oldCoin, trueCoin, userData.getCoin(), JSON.toJSONString(userData.getBuildingLevel()), new Date());
                    LogCrossLangYaBang.addLogLangYaBangPve(logLangYaBangPve);
                    return builder;
                }
            } else {    //没结算
                builder.setIsEventOver(0);
                builder.setGameEventData(LangYaBangPb.parseLangYaBangUserEventData(event, null));
                return builder;
            }
        }
    }

    public LangYaBangProto.DoPvpEventRespMsg.Builder dealPvp(long userId, int buildingType) {
        LangYaBangProto.DoPvpEventRespMsg.Builder builder = LangYaBangProto.DoPvpEventRespMsg.newBuilder();
        LangYaBangUserData userData = getUserData(userId);
        synchronized (userData) {
            int eventIdNow = userData.getEventIdNow();
            if (!checkCanOperateTime()) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_NO_OPERATE_TIME);
                return builder;
            }
            if (eventIdNow == 0) {
                logger.error("langYaBang user {} doPvp But eventId = 0", userId);
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_EVENT_DATA_ERROR);
                return builder;
            }
            LangYaRollDiceConfig diceConfigById = CrossLangYaBangConfigMgr.getDiceConfigById(activityId, eventIdNow);
            if (diceConfigById == null) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_CONFIG_ERROR);
                return builder;
            }
            if (diceConfigById.getType() != eLangYaBangEventType.pvp.getValue() && diceConfigById.getType() != eLangYaBangEventType.declareWarPvp.getValue()) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_CONFIG_ERROR);
                return builder;
            }
            LangYaUserEvent event = userData.getEvent();
            LangYaUserBuilding langYaTargetUserBuilding = event.getTargetBuilding().get(buildingType);
            if (langYaTargetUserBuilding == null) {
                userData.setEventIdNow(0);
                logger.error("LangYaBang targetId{} operateBuilding{} error ", event.getTargetId(), buildingType);
                userData.setEvent(LangYaUserEvent.getNewEmptyEvent());
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_EVENT_DATA_ERROR);
                return builder;
            }
            if (langYaTargetUserBuilding.getOperateStatus() == 1) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_PVP_CHOOSE_HAS_OPERATE);
                return builder;
            }

            langYaTargetUserBuilding.setOperateStatus(1);
            //先算一遍玩家能力
            reCalculateUserPatronsAbility(userData);
            //一个门课类型
            Map<Integer, LangYaTypePatrons> userPatronsInfoMap = userData.getUserPatronsInfoMap();

            int type = event.getBattlePatronType();
            //我的门客
            LangYaTypePatrons myBattleInfo = userPatronsInfoMap.get(type);

            //对方门客
            Map<Integer, LangYaTypePatrons> targetPatrons = event.getTargetPatrons();
            LangYaTypePatrons targetPatronsInfo = null;
            //如果有该类型的 直接给
            if (targetPatrons.containsKey(type)) {
                targetPatronsInfo = targetPatrons.get(type);
            } else {
                //防止特殊情况少了这个类型的
                for (LangYaTypePatrons tmpPatron : targetPatrons.values()) {
                    targetPatronsInfo = tmpPatron;
                    break;
                }
            }
            if (myBattleInfo == null) {
                logger.error("琅琊榜活动{},无法取得玩家{}的门课信息,已经重置玩家数据", activityId, userId);
                LogLangYaBangPvp logLangYaBangPvp = new LogLangYaBangPvp(activityId, userId, event.getTargetId(), -1, "", JSON.toJSONString(event.getTargetBuilding()), "", JSON.toJSONString(userData.getBuildingLevel()), event.getBelongDeclareWarUid(), event.getAddition(), "", 0, 0, userData.getCoin(), 0, 0, new Date());
                LogCrossLangYaBang.addLogLangYaBangPvp(logLangYaBangPvp);
                userData.setEventIdNow(0);
                userData.setEvent(LangYaUserEvent.getNewEmptyEvent());
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_EVENT_DATA_ERROR);
                return builder;
            }

            if (targetPatronsInfo == null) {
                logger.error("琅琊榜活动{},无法取得玩家{}的门课信息,已经重置玩家数据", activityId, event.getTargetId());
                LogLangYaBangPvp logLangYaBangPvp = new LogLangYaBangPvp(activityId, userId, event.getTargetId(), -1, "", JSON.toJSONString(event.getTargetBuilding()), "", JSON.toJSONString(userData.getBuildingLevel()), event.getBelongDeclareWarUid(), event.getAddition(), "", 0, 0, userData.getCoin(), 0, 0, new Date());
                LogCrossLangYaBang.addLogLangYaBangPvp(logLangYaBangPvp);
                userData.setEventIdNow(0);
                userData.setEvent(LangYaUserEvent.getNewEmptyEvent());
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_EVENT_DATA_ERROR);
                return builder;
            }

            builder.setRet(0);

            builder.setEnemyPatronsInfo(LangYaBangPb.parseTypePatronMsg(targetPatronsInfo));
            builder.setMyUserPatrons(LangYaBangPb.parseTypePatronMsg(myBattleInfo));


            int isWin = 0;
            if (diceConfigById.getType() == eLangYaBangEventType.declareWarPvp.getValue()) {
                if (myBattleInfo.getDeclareWarAttackAbility().compareTo(targetPatronsInfo.getPatronsInfos().getAbility()) >= 0) {
                    isWin = 1;
                    builder.setIsWin(1);
                    event.setPvpWinTime(event.getPvpWinTime() + 1);
                } else {
                    builder.setIsWin(0);
                }
            } else {
                if (myBattleInfo.getPatronsInfos().getAbility().compareTo(targetPatronsInfo.getPatronsInfos().getAbility()) >= 0) {
                    isWin = 1;
                    builder.setIsWin(1);
                    event.setPvpWinTime(event.getPvpWinTime() + 1);
                } else {
                    builder.setIsWin(0);
                }
            }


            //判断完重置一下能力
            //reCalculateUserPatronsAbility(userData);


            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(event.getTargetId());

            userData.setEventIdNow(0);
            userData.setEvent(LangYaUserEvent.getNewEmptyEvent());
            LangYaBangUserData enemyUserData = userDataMap.get(event.getTargetId());
            //如果是宣战 要拿对应的宣战数据出来
            LangYaBangDeclareWarData declareWarData = null;
            if (diceConfigById.getType() == eLangYaBangEventType.declareWarPvp.getValue()) {
                int declareWarUid = event.getBelongDeclareWarUid();
                String myUnionId = userData.getUnionId();
                //先找没结束的
                if (declareWarDataMap.containsKey(myUnionId)) {
                    Map<Integer, LangYaBangDeclareWarData> dataMap = declareWarDataMap.get(myUnionId);
                    if (dataMap.containsKey(declareWarUid)) {
                        declareWarData = dataMap.get(declareWarUid);
                    }
                }
                //可能已经结束了
                if (declareWarData == null) {
                    if (overTimeDeclareWarDataMap.containsKey(myUnionId)) {
                        Map<Integer, LangYaBangDeclareWarData> dataMap = overTimeDeclareWarDataMap.get(myUnionId);
                        if (dataMap.containsKey(declareWarUid)) {
                            declareWarData = dataMap.get(declareWarUid);
                        }
                    }
                }
            }

            //算积分
            int scoreAddition = 0;
            List<Integer> buildingAddition = CrossLangYaBangConfigMgr.getBuildingTypeAddition(activityId, eLangYaBangBuildingBuffType.pvpCoinScoreAdd.getValue(), userData.getBuildingLevel());
            if (buildingAddition != null) {
                scoreAddition += buildingAddition.get(1);
            }

            long winnerScoreChange = 0;
            long loserScoreChange = 0;
            int rankNum = -1;
            int declareRankScoreAdd = 0;
            //排名加成
            if (declareWarData != null) {
                List<UnionYRank> rankList = CrossYRankMgr.getSortUnionRankList(activityId, groupId, String.valueOf(eGamePlayerEventType.LangYaUnionScoreRank.getValue()));
                rankNum = CrossYRankMgr.getUnionRankNum(rankList, declareWarData.getDefenseUnionUid());
                declareRankScoreAdd = CrossLangYaBangConfigMgr.getEnemyUnionRankScoreAddition(activityId, rankNum);
            }

            if (isWin == 1) {
                if (diceConfigById.getType() == eLangYaBangEventType.pvp.getValue()) {
                    winnerScoreChange = diceConfigById.getEventParamList().get(4);
                    loserScoreChange = diceConfigById.getEventParamList().get(5);
                } else if (diceConfigById.getType() == eLangYaBangEventType.declareWarPvp.getValue()) {
                    winnerScoreChange = diceConfigById.getEventParamList().get(0);
                    loserScoreChange = diceConfigById.getEventParamList().get(1);

                }
                builder.setOriginalScore(winnerScoreChange);

                BigDecimal rankRate = BigDecimal.valueOf(1000 + declareRankScoreAdd).divide(BigDecimal.valueOf(1000), 2, RoundingMode.UP);
                BigDecimal areaRate = BigDecimal.valueOf(1000 + scoreAddition).divide(BigDecimal.valueOf(1000), 2, RoundingMode.UP);
                builder.addCalculateScoreParam(areaRate.doubleValue());
                if (diceConfigById.getType() == eLangYaBangEventType.declareWarPvp.getValue()) {
                    builder.addCalculateScoreParam(rankRate.doubleValue());
                }

                winnerScoreChange = BigDecimal.valueOf(winnerScoreChange)
                        .multiply(areaRate).setScale(2, RoundingMode.UP)
                        .multiply(rankRate).setScale(2, RoundingMode.UP)
                        .setScale(0, RoundingMode.UP)
                        .longValue();
            }

            long trueScoreAdd = winnerScoreChange * event.getAddition();
            userData.setScore(userData.getScore() + trueScoreAdd);


            long trueLoseScore = loserScoreChange * event.getAddition();
            enemyUserData.setScore(enemyUserData.getScore() - trueLoseScore);

            //宣战类型的pvp
            if (diceConfigById.getType() == eLangYaBangEventType.declareWarPvp.getValue()) {
                if (declareWarData != null) {
                    Map<Long, LangYaBangBeDeclareWarUserData> map = declareWarData.getBeDeclareUserDataMap();
                    if (map.containsKey(event.getTargetId())) {
                        LangYaBangBeDeclareWarUserData declareWarUserData = map.get(event.getTargetId());
                        declareWarUserData.setPvpWinTime(event.getPvpWinTime());
                        declareWarUserData.setLoseScore(trueLoseScore);
                    }
                }
            }
            long oldCoin = userData.getCoin();
            long trueCoin = 0;
            //算钱和道具
            Property property = new Property();
            long resultCoin = 0;

            String rewardString = "";
            //道具
            String reward = diceConfigById.getReward();
            if (!reward.equals("0")) {
                List<String> strings = StringUtils.stringToStringList(reward, "@");
                if (isWin == 1) {
                    rewardString = strings.get(0);
                } else {
                    rewardString = strings.get(1);
                }
            }


            property = PropertyHelper.parseNewStringToProperty(rewardString);
            builder.setReward(PropertyHelper.parsePropertyToString(property));
            //金币
            int coinAddition = 0;
            if (buildingAddition != null) {
                coinAddition += buildingAddition.get(0);
            }
            //int buildingTotalLevelCoinAddition = CrossLangYaBangConfigMgr.getBuildingTotalLevelCoinAddition(activityId, userData.getBuildingLevel());
            long originCoin = CrossLangYaBangConfigMgr.getRandomPvpCoinReward(activityId, diceConfigById.getType());

            //BigDecimal totalLevelAdd = BigDecimal.valueOf(buildingTotalLevelCoinAddition).divide(BigDecimal.valueOf(1000), 2, RoundingMode.UP);
            BigDecimal areaAdd = BigDecimal.valueOf(1).add(BigDecimal.valueOf(coinAddition)
                    .divide(BigDecimal.valueOf(1000), 2, RoundingMode.UP));
            BigDecimal winAdd = BigDecimal.valueOf(1);
            if (isWin == 1) {
                if (diceConfigById.getType() == eLangYaBangEventType.pvp.getValue()) {
                    winAdd = BigDecimal.valueOf(diceConfigById.getEventParamList().get(3)).divide(BigDecimal.valueOf(1000), 2, RoundingMode.UP);
                } else if (diceConfigById.getType() == eLangYaBangEventType.declareWarPvp.getValue()) {
                    winAdd = BigDecimal.valueOf(diceConfigById.getEventParamList().get(2)).divide(BigDecimal.valueOf(1000), 2, RoundingMode.UP);
                }
            }

            builder.setOriginCoin(originCoin);
            builder.addCalculateParam(areaAdd.doubleValue());
            if (isWin == 1) {
                builder.addCalculateParam(winAdd.doubleValue());
            }
            //builder.addCalculateParam(totalLevelAdd.doubleValue());

            resultCoin = BigDecimal.valueOf(originCoin)
                    .multiply(areaAdd)
                    .multiply(winAdd)
                    .setScale(0, RoundingMode.UP)
                    .longValue();
            if (diceConfigById.getType() == eLangYaBangEventType.declareWarPvp.getValue()) {
                if (declareWarData != null) {
                    int rankAddition = CrossLangYaBangConfigMgr.getEnemyUnionRankCoinAddition(activityId, rankNum);
                    BigDecimal rankAdd = BigDecimal.valueOf(1000 + rankAddition).divide(BigDecimal.valueOf(1000), 2, RoundingMode.UP);
                    builder.addCalculateParam(rankAdd.doubleValue());
                    if (rankAddition >= 0) {
                        resultCoin = BigDecimal.valueOf(resultCoin).multiply(rankAdd).setScale(0, RoundingMode.UP).longValue();
                    }
                }
            }
            trueCoin = resultCoin * event.getAddition();
            userData.setCoin(userData.getCoin() + trueCoin);
            userData.setHistoryCoinNum(userData.getHistoryCoinNum() + trueCoin);

            //如果是宣战 给发起者一份奖励
            if (diceConfigById.getType() == eLangYaBangEventType.declareWarPvp.getValue()) {
                if (declareWarData != null) {
                    if (declareWarData.getOpenUserId() != userId) {
                        LangYaBangUserData openUserData = userDataMap.get(declareWarData.getOpenUserId());
                        if (openUserData != null) {
                            //每次消耗宣战攻击次数发起宣战者收益 = 发起者收益基础值 * 发起者驻地等级倍率
                            long otherGiveCoin = trueCoin;
                            //物品收益
                            String giveOtherReward = CrossLangYaBangConfigMgr.getTokenUserRewardByOther(activityId);
                            openUserData.getOtherGiveReward().addProperty(PropertyHelper.parseNewStringToProperty(giveOtherReward));
                            openUserData.setOtherGiveCoin(openUserData.getOtherGiveCoin() + otherGiveCoin);
                            openUserData.setOtherGiveRewardNum(openUserData.getOtherGiveRewardNum() + 1);
                        }
                    }
                }
            }

            //生成战报发去被打的人那个服

            LangYaBangWarReportData warReportData = new LangYaBangWarReportData();
            warReportData.setActivityId(activityId);
            warReportData.setUserId(event.getTargetId());
            warReportData.setOtherUserId(userId);
            if (event.getPvpWinTime() > 0) {
                warReportData.setOperateType(eLangYaNoticeType.defenceOtherLose.getValue());
            } else {
                warReportData.setOperateType(eLangYaNoticeType.defenceOtherWin.getValue());
            }
            warReportData.setOperateTime(event.getPvpWinTime());
            warReportData.setScoreChange(trueScoreAdd);
            UserBaseInfo myBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
            if (myBaseInfo != null) {
                warReportData.setOtherData(LangYaBangPb.parseUserBaseInfoToBriefData(myBaseInfo));
            }
            warReportData.setTime(System.currentTimeMillis());
            warReportData.setGoodReward("");
            warReportData.setSelfScoreChange(trueLoseScore);
            if (userBaseInfo != null) {
                syncWarReport(warReportData, event.getTargetId(), (int) userBaseInfo.getServerId());
                //同步那个人的成就
                syncScoreChangeToServer(activityId, (int) userBaseInfo.getServerId(), event.getTargetId(), enemyUserData.getScore());
            } else {
                syncWarReport(warReportData, event.getTargetId(), (int) enemyUserData.getServerId());
                //同步那个人的成就
                syncScoreChangeToServer(activityId, (int) enemyUserData.getServerId(), event.getTargetId(), enemyUserData.getScore());
            }


            //回包的东西
            builder.setIsEventOver(1);
            builder.setScoreReward(winnerScoreChange);
            builder.setCoinReward(resultCoin);
            builder.setGameEventData(LangYaBangPb.parseLangYaBangUserEventData(event, userBaseInfo));
            builder.setRewardPowerAddition(event.getAddition());
            builder.setOtherLoseScore(trueLoseScore);
            LangYaBangProto.LangYaBangUserDataSyncMsg.Builder langYaBangUserData = LangYaBangPb.parseLangYaBangUserData(userData, null, 0);
            builder.setUserData(langYaBangUserData);
            int belongDeclareWarId = 0;
            if (declareWarData != null) {
                belongDeclareWarId = declareWarData.getDeclareWarUid();
            }
            property.goodCountMultiNum(event.getAddition());
            StringBuffer patronsInfo = new StringBuffer();
            for (LangYaTypePatrons langYaTypePatrons : targetPatrons.values()) {
                patronsInfo.append(langYaTypePatrons.parseBaseAbilityString());
            }

            LogLangYaBangPvp logLangYaBangPvp = new LogLangYaBangPvp(activityId, userId, event.getTargetId(), isWin, patronsInfo.toString(), JSON.toJSONString(event.getTargetBuilding()), myBattleInfo.parseBaseAbilityString(), JSON.toJSONString(userData.getBuildingLevel()), belongDeclareWarId, event.getAddition(), PropertyHelper.parsePropertyToString(property), oldCoin, trueCoin, userData.getCoin(), trueScoreAdd, trueLoseScore, new Date());
            LogCrossLangYaBang.addLogLangYaBangPvp(logLangYaBangPvp);
        }

        return builder;
    }

    public LangYaBangProto.LangYaBangUsePowerItemRespMsg.Builder addPower(long userId, int useNum) {
        LangYaBangUserData userData = getUserData(userId);
        //正常情况恢复计算体力不会超过上限
        calculatePower(userId);

        int energyItemId = CrossLangYaBangConfigMgr.getConfig(activityId).getEnergyItemId();
        GoodsInfo goodsInfo = GoodsMgr.getGoodsInfo(energyItemId);
        int recoveryNum = goodsInfo.getParamList().get(0).intValue();
        userData.setPower(userData.getPower() + useNum * recoveryNum);
        //更新历史最高体力
        if (userData.getPower() > userData.getHistoryPower()){
            userData.setHistoryPower(userData.getPower());
        }
        LangYaBangProto.LangYaBangUsePowerItemRespMsg.Builder builder = LangYaBangProto.LangYaBangUsePowerItemRespMsg.newBuilder();
        builder.setRet(0);
        builder.setLastRecoveryTime(userData.getLastRecoveryTime());
        builder.setNowPower(userData.getPower());
        builder.setHistoryHighestPower(userData.getHistoryPower());
        return builder;
    }

    public long getUnionScore(String unionUid) {
        LangYaUnionData langYaUnionData = unionMap.get(unionUid);
        if (langYaUnionData == null) {
            return 0;
        }
        return langYaUnionData.getScoreNow();
    }

    public LangYaBangProto.LangYaBangUpgradeBuildingRespMsg.Builder upgradeBuilding(long userId, int buildingType) {
        LangYaBangProto.LangYaBangUpgradeBuildingRespMsg.Builder builder = LangYaBangProto.LangYaBangUpgradeBuildingRespMsg.newBuilder();
        if (!checkCanOperateTime()) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_NO_OPERATE_TIME);
            return builder;
        }
        LangYaBangUserData userData = getUserData(userId);
        LangYaBangAreaConfig nextLangYaBangAreaConfig;
        long needCoin = -1;
        long coinBefore;
        LangYaBangAreaConfig langYaBangAreaConfig;
        synchronized (userData){
            int nowLevel = userData.getBuildingLevel().get(buildingType);
            langYaBangAreaConfig = CrossLangYaBangConfigMgr.getLangYaBangAreaConfig(activityId, buildingType, nowLevel);
            if (langYaBangAreaConfig == null) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_CONFIG_ERROR);
                return builder;
            }
            needCoin = StringUtils.string2longSafe(langYaBangAreaConfig.getCost(), Long.MAX_VALUE);
            if (needCoin == -1) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_BUILDING_LEVEL_MAX);
                return builder;
            }

            if (userData.getCoin() < needCoin) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_COIN_NO_ENOUGH);
                return builder;
            }

            nextLangYaBangAreaConfig = CrossLangYaBangConfigMgr.getNextLangYaBangAreaConfig(activityId, buildingType, nowLevel);
            if (nextLangYaBangAreaConfig == null) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_CONFIG_ERROR);
                return builder;
            }
            if (!CrossLangYaBangConfigMgr.checkAreaLvEnough(activityId, userData.getBuildingLevel(), nextLangYaBangAreaConfig)) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_UPGRADE_BUILDING_LEVEL_NO_ENOUGH);
                return builder;
            }
            coinBefore = userData.getCoin();
            userData.setCoin(coinBefore - needCoin);
            userData.getBuildingLevel().put(buildingType, nextLangYaBangAreaConfig.getAreaLvId());
        }


        builder.setRet(0);
        builder.setCostCoin(needCoin);

        LangYaBangProto.LangYaUserBuildingData.Builder singleBuilder = LangYaBangProto.LangYaUserBuildingData.newBuilder();
        singleBuilder.setBuildingId(buildingType);
        singleBuilder.setLevelId(nextLangYaBangAreaConfig.getAreaLvId());
        if (!Objects.equals(langYaBangAreaConfig.getAreaValue(), nextLangYaBangAreaConfig.getAreaValue())){
            singleBuilder.setOperateStatus(1);
        }else {
            singleBuilder.setOperateStatus(0);
        }
        builder.setUpdateBuilding(singleBuilder);
        reCalculateUserPatronsAbility(userData);
        String reward = nextLangYaBangAreaConfig.getReward();
        if (!StringUtils.isNullOrEmpty(reward)){
            if (!reward.equals("0")){
                Property property = PropertyHelper.parseNewStringToProperty(reward);
                builder.setReward(PropertyHelper.parsePropertyToString(property));
            }
        }

        LogLangYaBangUpgradeBuilding logLangYaBangUpgradeBuilding = new LogLangYaBangUpgradeBuilding(activityId,userId, langYaBangAreaConfig.getAreaLvId(), nextLangYaBangAreaConfig.getAreaLvId(),coinBefore,needCoin,userData.getCoin(),reward,new Date());
        LogCrossLangYaBang.addLogLangYaBangUpgradeBuildings(logLangYaBangUpgradeBuilding);

        builder.setUserData(LangYaBangPb.parseLangYaBangUserData(userData, null, getUnionScore(userData.getUnionId())));

        return builder;
    }

    public LangYaBangProto.InitiateDeclareWarRespMsg.Builder declareWar(long userId, String unionUid) {
        LangYaBangProto.InitiateDeclareWarRespMsg.Builder builder = LangYaBangProto.InitiateDeclareWarRespMsg.newBuilder();
        if (!checkCanOperateTime()) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_NO_OPERATE_TIME);
            return builder;
        }
        LangYaBangConfig config = CrossLangYaBangConfigMgr.getConfig(activityId);
        if (config == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_CONFIG_ERROR);
            return builder;
        }

        if (unionMap.get(unionUid) == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_UNION_NO_EXIST);
            return builder;
        }
        LangYaUnionData targetUnionData = unionMap.get(unionUid);
        if (targetUnionData.getUserIdSet().isEmpty()) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_UNION_NO_USER);
            return builder;
        }
        UnionActivityGroupUnion unionData = Cross2UnionActivityGroupMgr.getUnionData(activityId, targetUnionData.getUnionUid());

        if (unionData == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_UNION_NO_EXIST);
            return builder;
        }
        LangYaBangUserData userData = getUserData(userId);
        if (userData == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_CROSS_DATA_NO_INIT);
            return builder;
        }
        String myUnionId = userData.getUnionId();
        if (StringUtils.isNullOrEmpty(myUnionId)) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_CROSS_DATA_NO_INIT);
            return builder;
        }
        UnionActivityGroupUnion myUnionData = Cross2UnionActivityGroupMgr.getUnionData(activityId, myUnionId);
        if (myUnionData == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_UNION_NO_EXIST);
            return builder;
        }

        //随机人出来 初始化数据
        Map<Long, LangYaBangBeDeclareWarUserData> randomUserBeDeclareData = getRandomUserBeDeclareData(targetUnionData.getUserIdSet(), config.getTokenNum().get(0) + config.getTokenNum().get(1));
        LangYaBangDeclareWarData initDeclareWarData = getInitDeclareWarData(userId, myUnionId, targetUnionData.getUnionUid(), randomUserBeDeclareData);
        if (initDeclareWarData == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_UNION_DATA_ERROR);
            return builder;
        }


        //加到map
        if (!declareWarDataMap.containsKey(myUnionId)) {
            synchronized (declareWarDataMap) {
                if (!declareWarDataMap.containsKey(myUnionId)) {
                    declareWarDataMap.put(myUnionId, new ConcurrentHashMap<>());
                }
            }
        }
        declareWarDataMap.get(myUnionId).put(initDeclareWarData.getDeclareWarUid(), initDeclareWarData);

        //加仇恨值
        Map<String, Integer> hateValueMap = targetUnionData.getHateValueMap();
        if (hateValueMap == null) {
            targetUnionData.setHateValueMap(new ConcurrentHashMap<>());
        }
        hateValueMap = targetUnionData.getHateValueMap();
        if (!hateValueMap.containsKey(myUnionId)) {
            hateValueMap.put(myUnionId, 1);
        } else {
            hateValueMap.put(myUnionId, hateValueMap.get(myUnionId) + 1);
        }
        targetUnionData.setUpdateOption();

        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
        builder.setRet(0);
        builder.setSimpleInfo(LangYaBangPb.parseLangYaBangDeclareWarSimpleInfo(initDeclareWarData, unionData.getUnionBaseInfo(), userBaseInfo));

        //给个公告
        UnionBaseInfo targetUnionBaseInfo = unionData.getUnionBaseInfo();
        UnionBaseInfo unionBaseInfo = myUnionData.getUnionBaseInfo();
        LangYaDeclareWarNoticeData warNoticeData = new LangYaDeclareWarNoticeData();
        warNoticeData.setActivityId(activityId);
        warNoticeData.setGroupId(groupId);
        warNoticeData.setDeclareWarUid(initDeclareWarData.getDeclareWarUid());
        warNoticeData.setAttackUnion(LangYaBangPb.parseUnionBriefData(myUnionId, unionBaseInfo));
        warNoticeData.setDefendUnion(LangYaBangPb.parseUnionBriefData(unionUid, targetUnionBaseInfo));
        warNoticeData.setAttackUser(LangYaBangPb.parseUserBaseInfoToBriefData(userBaseInfo));
        warNoticeData.setTime(System.currentTimeMillis());
        warNoticeData.setInsertOption();
        addDeclareWarNotice(warNoticeData);

        syncDeclareWarNoticeToServer(warNoticeData);

        UnionActivityGroup groupData = Cross2UnionActivityGroupMgr.getGroupData(activityId, groupId);
        if (groupData != null) {
            for (long serverId : groupData.getServerSet()) {
                syncUnionRedDotToServer(1, 1, (int) serverId, userData.getUnionId());
            }
        }
        syncUserRedDotToServer(2, 1, (int) userData.getServerId(), userId);
        builder.setNoticeData(LangYaBangPb.parseNoticeMsg(warNoticeData));

        return builder;
    }

    public void addDeclareWarNotice(LangYaDeclareWarNoticeData warNoticeData){
        synchronized (needInsertNoticeDataList){
            needInsertNoticeDataList.add(warNoticeData);
            if (noticeDataList.size() >= CrossLangYaBangConfigMgr.getMaxNoticeAndReportNum(activityId)){
                noticeDataList.remove(0);
            }
            noticeDataList.add(warNoticeData);
        }

    }

    /**
     * 同步红点给用户 类型1为宣战 类型2为自己是否打完
     */
    public void syncUserRedDotToServer(int type, int state, int serverId, long userId) {
        LangYaBangProto.LangYaBangRedDotSyncMsg.Builder builder = LangYaBangProto.LangYaBangRedDotSyncMsg.newBuilder();
        LangYaBangProto.redDotSync.Builder redDot = LangYaBangProto.redDotSync.newBuilder();
        redDot.setType(type);
        redDot.setState(state);
        builder.setRed(redDot);
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(ClientProtocol.U_LANG_YA_BANG_RED_DOT_SYNC, builder);
        MessageHelper.sendPacket(serverId, userId, pbMsg);
    }

    /**
     * 同步红点给商会  类型1为宣战
     */
    public void syncUnionRedDotToServer(int type, int state, int serverId, String unionUid) {

        UnionActivityGroupUnion unionData = Cross2UnionActivityGroupMgr.getUnionData(activityId, unionUid);
        if (unionData == null){
            logger.error("活动id{}琅琊榜找不到商会信息unionId {}",activityId,unionUid);
            return;
        }

        LangYaBangProto.LangYaBangRedDotSyncMsg.Builder toClient = LangYaBangProto.LangYaBangRedDotSyncMsg.newBuilder();
        LangYaBangProto.redDotSync.Builder redDot = LangYaBangProto.redDotSync.newBuilder();
        redDot.setType(type);
        redDot.setState(state);
        toClient.setRed(redDot);

        ConcurrentHashMap<Long, UnionActivityGroupUser> userMap = unionData.getUserMap();
        for (UnionActivityGroupUser user : userMap.values()) {
            long memberServer = user.getServerId();
            YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(ClientProtocol.U_LANG_YA_BANG_RED_DOT_SYNC, toClient);
            MessageHelper.sendPacket(memberServer, user.getUserId(), pbMsg);
        }


    }


    public void syncDeclareWarNoticeToServer(LangYaDeclareWarNoticeData warNoticeData) {
        LangYaBangProto.LangYaBangDeclareWarNoticeSyncMsg.Builder builder = LangYaBangProto.LangYaBangDeclareWarNoticeSyncMsg.newBuilder();
        builder.setActivityId(activityId);
        builder.setGroupId(groupId);
        builder.setNoticeDeclareWarData(LangYaBangPb.parseNoticeMsg(warNoticeData));
        UnionActivityGroup groupData = Cross2UnionActivityGroupMgr.getGroupData(activityId, groupId);
        Set<Long> serverSet = groupData.getServerSet();
        for (long serverId : serverSet) {
            YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(GameProtocol.S_LANG_YA_BANG_SYNC_NEW_DECLARE_WAR_FROM_CROSS, builder);
            MessageHelper.sendPacket(serverId, 0, pbMsg);
        }
    }

    public Map<Long, LangYaBangBeDeclareWarUserData> getRandomUserBeDeclareData(Set<Long> userIdSet, int needNum) {

        Map<Long, LangYaBangBeDeclareWarUserData> map = new ConcurrentHashMap<>();
        List<Long> userIdList = new ArrayList<>(userIdSet);
        List<Integer> differentRandomNum = randomHelper.getRandomDistinctInteger(0, userIdList.size() - 1, needNum);
        for (int index : differentRandomNum) {
            long userId = userIdList.get(index);
            LangYaBangBeDeclareWarUserData langYaBangBeDeclareWarUserData = new LangYaBangBeDeclareWarUserData();
            langYaBangBeDeclareWarUserData.setUserId(userId);
            langYaBangBeDeclareWarUserData.setIsBeenAttack(0);
            langYaBangBeDeclareWarUserData.setLoseScore(0);
            langYaBangBeDeclareWarUserData.setPvpWinTime(0);
            langYaBangBeDeclareWarUserData.setAttackUserId(0);
            map.put(langYaBangBeDeclareWarUserData.getUserId(), langYaBangBeDeclareWarUserData);
        }
        return map;
    }

    private LangYaBangDeclareWarData getInitDeclareWarData(long userId, String myUnionId, String enemyUnionId, Map<Long, LangYaBangBeDeclareWarUserData> map) {
        LangYaBangDeclareWarData unionDeclareWarData = new LangYaBangDeclareWarData();
        unionDeclareWarData.setActivityId(activityId);
        unionDeclareWarData.setGroupId(groupId);
        int uid = declareWarUid.getAndAdd(1);
        unionDeclareWarData.setDeclareWarUid(uid);
        unionDeclareWarData.setAttackUnionUid(myUnionId);
        unionDeclareWarData.setDefenseUnionUid(enemyUnionId);
        unionDeclareWarData.setOpenUserId(userId);
        LangYaBangConfig config = CrossLangYaBangConfigMgr.getConfig(activityId);
        if (config == null) {
            return null;
        }
        //取出当时的排行
        List<UnionYRank> rankList = CrossYRankMgr.getSortUnionRankList(activityId, groupId, String.valueOf(eGamePlayerEventType.LangYaUnionScoreRank.getValue()));
        int rankNum = CrossYRankMgr.getUnionRankNum(rankList, enemyUnionId);

        unionDeclareWarData.setDefenseUnionRank(rankNum);

        unionDeclareWarData.setOpenUserRemainTimes(config.getTokenNum().get(0));
        unionDeclareWarData.setOtherUserRemainTimes(config.getTokenNum().get(1));
        unionDeclareWarData.setIsOver(0);
        unionDeclareWarData.setBeDeclareUserDataMap(map);
        unionDeclareWarData.setOpenTime(System.currentTimeMillis());
        unionDeclareWarData.setInsertOption();

        return unionDeclareWarData;
    }

    public LangYaBangProto.GetHistorySimpleDeclareWarInfoRespMsg.Builder getHistoryDeclareWarSimple(long userId) {
        LangYaBangProto.GetHistorySimpleDeclareWarInfoRespMsg.Builder builder = LangYaBangProto.GetHistorySimpleDeclareWarInfoRespMsg.newBuilder();
        LangYaBangUserData userData = userDataMap.get(userId);
        if (userData == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_CROSS_DATA_NO_INIT);
            return builder;
        }
        String unionId = userData.getUnionId();
        if (StringUtils.isNullOrEmpty(unionId)) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_UNION_NO_EXIST);
            return builder;
        }
        LangYaUnionData langYaUnionData = unionMap.get(unionId);
        if (langYaUnionData == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_UNION_NO_EXIST);
            return builder;
        }
        Map<Integer, LangYaBangDeclareWarData> map = declareWarDataMap.get(unionId);
        if (map == null) {
            synchronized (declareWarDataMap) {
                if (map == null) {
                    declareWarDataMap.put(unionId, new ConcurrentHashMap<>());
                    map = declareWarDataMap.get(unionId);
                }
            }
        }
        builder.setRet(0);
        for (LangYaBangDeclareWarData declareWarData : map.values()) {


            UnionActivityGroupUnion unionData = Cross2UnionActivityGroupMgr.getUnionData(activityId, declareWarData.getDefenseUnionUid());
            if (unionData == null) {
                continue;
            }
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(declareWarData.getOpenUserId());
            LangYaBangProto.LangYaBangDeclareWarSimpleInfo.Builder simpleInfo = LangYaBangPb.parseLangYaBangDeclareWarSimpleInfo(declareWarData,unionData.getUnionBaseInfo(),userBaseInfo);
            builder.addSimpleInfo(simpleInfo);
        }
        Map<Integer, LangYaBangDeclareWarData> overTimeMap = overTimeDeclareWarDataMap.get(unionId);
        if (overTimeMap == null) {
            overTimeMap = overTimeDeclareWarDataMap.get(unionId);
            synchronized (overTimeDeclareWarDataMap) {
                if (overTimeMap == null) {
                    overTimeDeclareWarDataMap.put(unionId, new ConcurrentHashMap<>());
                    overTimeMap = overTimeDeclareWarDataMap.get(unionId);
                }
            }
        }

        for (LangYaBangDeclareWarData declareWarData : overTimeMap.values()) {
            LangYaBangProto.LangYaBangDeclareWarSimpleInfo.Builder simpleInfo = LangYaBangProto.LangYaBangDeclareWarSimpleInfo.newBuilder();
            simpleInfo.setDeclareWarUid(declareWarData.getDeclareWarUid());
            UnionActivityGroupUnion unionData = Cross2UnionActivityGroupMgr.getUnionData(activityId, declareWarData.getDefenseUnionUid());
            if (unionData == null) {
                continue;
            }
            simpleInfo.setTargetUnionInfo(UnionBasePb.parseUnionBaseTempMsg(unionData.getUnionBaseInfo()));
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(declareWarData.getOpenUserId());
            if (userBaseInfo != null) {
                simpleInfo.setDeclareUser(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
            }else {
                logger.error("琅琊榜活动{}取不到跨服玩家信息:{}",activityId,declareWarData.getOpenUserId());
            }
            simpleInfo.setOpenUserRemainTimes(declareWarData.getOpenUserRemainTimes());
            simpleInfo.setOtherUserRemainTimes(declareWarData.getOtherUserRemainTimes());
            simpleInfo.setIsOver(declareWarData.getIsOver());
            simpleInfo.setUnionUid(declareWarData.getDefenseUnionUid());
            builder.addSimpleInfo(simpleInfo);
        }
        return builder;
    }

    public LangYaBangProto.GetHistoryDeclareWarDetailInfoRespMsg.Builder getHistoryDeclareWarDetail(long userId, int declareWarDetail,String belongUnionId) {
        LangYaBangProto.GetHistoryDeclareWarDetailInfoRespMsg.Builder builder = LangYaBangProto.GetHistoryDeclareWarDetailInfoRespMsg.newBuilder();
        LangYaBangUserData langYaBangUserData = userDataMap.get(userId);
        if (langYaBangUserData == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_CROSS_DATA_NO_INIT);
            return builder;
        }

        if (StringUtils.isNullOrEmpty(belongUnionId)) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_UNION_NO_EXIST);
            return builder;
        }

        Map<Integer, LangYaBangDeclareWarData> map = declareWarDataMap.get(belongUnionId);
        Map<Integer, LangYaBangDeclareWarData> overTimeMap = overTimeDeclareWarDataMap.get(belongUnionId);
        if (map == null && overTimeMap == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_DECLARE_WAR_ID_NO_EXIST);
            return builder;
        }
        LangYaBangDeclareWarData declareWarData = null;
        if (map != null && map.containsKey(declareWarDetail)) {
            declareWarData = map.get(declareWarDetail);
        }
        if (overTimeMap != null && overTimeMap.containsKey(declareWarDetail)) {
            declareWarData = overTimeMap.get(declareWarDetail);
        }
        if (declareWarData == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_DECLARE_WAR_ID_NO_EXIST);
            return builder;
        }

        Map<Long, LangYaBangBeDeclareWarUserData> beDeclareUserDataMap = declareWarData.getBeDeclareUserDataMap();
        for (LangYaBangBeDeclareWarUserData langYaBangBeDeclareWarUserData : beDeclareUserDataMap.values()) {
            LangYaBangProto.BeDeclareUserData.Builder userBuilder = LangYaBangProto.BeDeclareUserData.newBuilder();
            userBuilder.setUserId(langYaBangBeDeclareWarUserData.getUserId());
            UserBaseInfo beAttackUserBaseInfo = CrossUserMgr.getUserBaseInfo(langYaBangBeDeclareWarUserData.getUserId());
            if (beAttackUserBaseInfo == null) {
                continue;
            }
            LangYaBangUserData userData = userDataMap.get(langYaBangBeDeclareWarUserData.getUserId());
            if (userData == null) {
                continue;
            }
            builder.setRet(0);
            userBuilder.setUserBaseData(PlayerBasePb.parsePlayerBaseTempMsg(beAttackUserBaseInfo));
            userBuilder.setIsBeenAttack(langYaBangBeDeclareWarUserData.getIsBeenAttack());
            userBuilder.setNowScore(userData.getScore());
            userBuilder.setLoseScore(langYaBangBeDeclareWarUserData.getLoseScore());
            userBuilder.setWinTime(langYaBangBeDeclareWarUserData.getPvpWinTime());
            if (langYaBangBeDeclareWarUserData.getAttackUserId()!=0){
                UserBaseInfo attackUserBaseInfo = CrossUserMgr.getUserBaseInfo(langYaBangBeDeclareWarUserData.getAttackUserId());
                if (attackUserBaseInfo != null) {
                    userBuilder.setAttackUserData(PlayerBasePb.parsePlayerBaseTempMsg(attackUserBaseInfo));
                }else {
                    logger.error("琅琊榜活动{},找不到玩家{}基础信息",activityId,langYaBangBeDeclareWarUserData.getAttackUserId());
                }
            }

            builder.addBeDeclareUserData(userBuilder);
        }
        UnionActivityGroupUnion unionData = Cross2UnionActivityGroupMgr.getUnionData(activityId, declareWarData.getDefenseUnionUid());
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(declareWarData.getOpenUserId());

        LangYaBangProto.LangYaBangDeclareWarSimpleInfo.Builder simpleInfo = LangYaBangPb.parseLangYaBangDeclareWarSimpleInfo(declareWarData, unionData.getUnionBaseInfo(), userBaseInfo);

        builder.setSimpleInfo(simpleInfo);
        return builder;
    }

    public Map<String, Integer> getHateMap(String unionUid) {
        LangYaUnionData unionData = unionMap.get(unionUid);
        if (unionData == null) {
            return new ConcurrentHashMap<>();
        }
        return unionData.getHateValueMap();
    }

    LangYaBangProto.ChooseDeclareWarBattleUserResp.Builder chooseDeclareWarBattleUser(long userId, long enemyUserId, int declareUid) {

        LangYaBangProto.ChooseDeclareWarBattleUserResp.Builder builder = LangYaBangProto.ChooseDeclareWarBattleUserResp.newBuilder();

        LangYaRollDiceConfig rollDiceConfigByType = CrossLangYaBangConfigMgr.getRollDiceConfigByType(activityId, eLangYaBangEventType.declareWarPvp.getValue());
        if (rollDiceConfigByType == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_CONFIG_ERROR);
            return builder;
        }
        LangYaBangUserData userData = userDataMap.get(userId);
        if (userData == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_CROSS_DATA_NO_INIT);
            return builder;
        }
        String unionId = userData.getUnionId();
        if (StringUtils.isNullOrEmpty(unionId)) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_UNION_NO_EXIST);
            return builder;
        }
        Map<Integer, LangYaBangDeclareWarData> integerLangYaBangDeclareWarDataMap = declareWarDataMap.get(unionId);
        if (integerLangYaBangDeclareWarDataMap == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_DECLARE_WAR_IS_END);
            return builder;
        }
        if (!integerLangYaBangDeclareWarDataMap.containsKey(declareUid)) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_DECLARE_WAR_IS_END);
            return builder;
        }
        LangYaBangDeclareWarData declareWarData = integerLangYaBangDeclareWarDataMap.get(declareUid);
        if (!declareWarData.getBeDeclareUserDataMap().containsKey(enemyUserId)) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_USER_NO_IN_DECLARE_LIST);
            return builder;
        }
        LangYaBangUserData enemyLangYaData = userDataMap.get(enemyUserId);
        if (enemyLangYaData == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_USER_NO_IN_DECLARE_LIST);
            return builder;
        }
        LangYaBangBeDeclareWarUserData enemyBeDeclareData = declareWarData.getBeDeclareUserDataMap().get(enemyUserId);
        if (enemyBeDeclareData.getIsBeenAttack() != 0) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_USER_HAS_BEEN_HIT);
            return builder;
        }
        if (declareWarData.getIsOver() == 1) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_DECLARE_WAR_IS_END);
            return builder;
        }
        calculatePower(userId);
        int energyUsed = CrossLangYaBangConfigMgr.getConfig(activityId).getDeclareWarBattleEnergyUsed();
        if (userData.getPower() < energyUsed) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_NO_POWER);
            return builder;
        }
        int hasAttackTimeThisDeclareWar = 0;
        for (LangYaBangBeDeclareWarUserData declareWarUserData : declareWarData.getBeDeclareUserDataMap().values()) {
            if (declareWarUserData.getAttackUserId() == userId) {
                hasAttackTimeThisDeclareWar++;
            }
        }

        //开启宣战本人打
        if (userId == declareWarData.getOpenUserId()) {
            if (hasAttackTimeThisDeclareWar >= 1) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_HAS_NO_DECLARE_PVP_TIME);
                return builder;
            }
            int openUserRemainTimes = declareWarData.getOpenUserRemainTimes();
            if (openUserRemainTimes <= 0) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_HAS_NO_DECLARE_PVP_TIME);
                return builder;
            } else {
                declareWarData.setOpenUserRemainTimes(openUserRemainTimes - 1);
            }
        } else {        //开启宣战别人打
            if (hasAttackTimeThisDeclareWar >= 1) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_HAS_NO_DECLARE_PVP_TIME);
                return builder;
            }
            int otherUserRemainTimes = declareWarData.getOtherUserRemainTimes();
            if (otherUserRemainTimes <= 0) {
                builder.setRet(GameErrorCode.E_LANG_YA_BANG_HAS_NO_DECLARE_PVP_TIME);
                return builder;
            } else {
                declareWarData.setOtherUserRemainTimes(otherUserRemainTimes - 1);
            }
        }
        userData.setPower(userData.getPower() - energyUsed);
        userData.setHasAllUsedPower(userData.getHasAllUsedPower()+energyUsed);

        enemyBeDeclareData.setIsBeenAttack(1);
        enemyBeDeclareData.setAttackUserId(userData.getUserId());
        //发起者是不是本人 都先给奖励到暂存


        if (isDeclareWarOver(declareWarData)) {
            declareWarData.setIsOver(1);
            DaoHelper.getLangYaBangDeclareWarDataDaoImpl().update(declareWarData);
            overTimeDeclareWarDataMap.putIfAbsent(declareWarData.getAttackUnionUid(), new ConcurrentHashMap<>());
            overTimeDeclareWarDataMap.get(declareWarData.getAttackUnionUid()).put(declareWarData.getDeclareWarUid(), integerLangYaBangDeclareWarDataMap.remove(declareWarData.getDeclareWarUid()));
        }
        declareWarData.setUpdateOption();

        userData.setEvent(LangYaUserEvent.getNewEmptyEvent());
        userData.setEventIdNow(rollDiceConfigByType.getId());
        LangYaUserEvent event = userData.getEvent();
        event.setTargetId(enemyUserId);
        Map<Integer, Integer> buildingLevel = enemyLangYaData.getBuildingLevel();
        Map<Integer, LangYaUserBuilding> pvpEnemyBuildingData = getPvpEnemyBuildingData(buildingLevel);
        event.setTargetBuilding(pvpEnemyBuildingData);
        event.setTargetPatrons(new ConcurrentHashMap<>(enemyLangYaData.getUserPatronsInfoMap()));
        event.setAddition(1);
        event.setRemainOperateTime(5);
        event.setPvpWinTime(0);
        event.setBelongDeclareWarUid(declareUid);
        int randomType = random.nextInt(5) + 1;
        event.setBattlePatronType(randomType);
        userData.setUpdateOption();
        builder.setRet(0);
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(enemyUserId);
        LangYaBangProto.LangYaBangUserDataSyncMsg.Builder userBuilder = LangYaBangPb.parseLangYaBangUserData(userData, userBaseInfo, 0L);
        builder.setUserData(userBuilder);

        if (isAllDeclareWarOver(userData.getUnionId())) {
            UnionActivityGroup groupData = Cross2UnionActivityGroupMgr.getGroupData(activityId, groupId);
            if (groupData != null) {
                for (long serverId : groupData.getServerSet()) {
                    syncUnionRedDotToServer(1, 0, (int) serverId, userData.getUnionId());
                }
            }
        }

        if (isMyDeclareWarTimeOver(userData.getUnionId(),userId)){
            syncUserRedDotToServer(2,0,(int) userData.getServerId(),userId);
        }
        return builder;
    }

    private boolean isAllDeclareWarOver(String unionUid) {
        if (declareWarDataMap.get(unionUid) == null) {
            return true;
        }
        if (declareWarDataMap.get(unionUid).isEmpty()) {
            return true;
        }
        for (LangYaBangDeclareWarData data : declareWarDataMap.get(unionUid).values()) {
            if (data.getIsOver() == 0) {
                return false;
            }
        }
        return true;
    }

    private boolean isMyDeclareWarTimeOver(String unionUid,long myUserId) {
        if (declareWarDataMap.get(unionUid) == null) {
            return true;
        }
        if (declareWarDataMap.get(unionUid).isEmpty()) {
            return true;
        }
        for (LangYaBangDeclareWarData data : declareWarDataMap.get(unionUid).values()) {
            if (data.getIsOver() == 1) {
                continue;
            }
            Map<Long, LangYaBangBeDeclareWarUserData> beDeclareUserDataMap = data.getBeDeclareUserDataMap();
            if (beDeclareUserDataMap == null) {
                continue;
            }
            int remainTime = 0;
            int myAttackTime = 0;
            for (LangYaBangBeDeclareWarUserData beDeclareUserData:beDeclareUserDataMap.values()){
                if (beDeclareUserData.getIsBeenAttack() == 0){
                    remainTime++;
                }
                if (beDeclareUserData.getAttackUserId() == myUserId){
                    myAttackTime ++;
                }
            }
            if (myAttackTime == 0 && remainTime > 0){
                return false;
            }
        }
        return true;
    }


    private boolean isDeclareWarOver(LangYaBangDeclareWarData declareWarData) {
        Map<Long, LangYaBangBeDeclareWarUserData> beDeclareUserDataMap = declareWarData.getBeDeclareUserDataMap();
        boolean isOver = true;
        for (LangYaBangBeDeclareWarUserData userData : beDeclareUserDataMap.values()) {
            if (userData.getIsBeenAttack() == 0) {
                isOver = false;
            }
        }
        if (declareWarData.getOpenUserRemainTimes() <= 0 && declareWarData.getOtherUserRemainTimes() <= 0) {
            isOver = true;
        }

        return isOver;
    }

    public LangYaBangProto.LangYaGetOtherHelpRewardRespMsg.Builder getOtherHelpReward(long userId) {
        LangYaBangProto.LangYaGetOtherHelpRewardRespMsg.Builder builder = LangYaBangProto.LangYaGetOtherHelpRewardRespMsg.newBuilder();
        if (!checkCanOperateTime()) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_NO_OPERATE_TIME);
            return builder;
        }
        LangYaBangUserData userData = getUserData(userId);
        if (userData == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_CROSS_DATA_NO_INIT);
            return builder;
        }
        Property otherGiveReward = userData.getOtherGiveReward();
        if (otherGiveReward.isNothing() && userData.getOtherGiveScore() <= 0 && userData.getOtherGiveCoin() <= 0) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_OTHER_HELP_REWARD_EMPTY);
            return builder;
        }
        if (!otherGiveReward.isNothing()) {
            userData.setOtherGiveReward(new Property());
            builder.setGoodsReward(PropertyHelper.parsePropertyToString(otherGiveReward));
        }
        long otherGiveCoin = userData.getOtherGiveCoin();
        if (otherGiveCoin > 0) {
            userData.setOtherGiveCoin(0);
            userData.setCoin(userData.getCoin() + otherGiveCoin);
            userData.setHistoryCoinNum(userData.getHistoryCoinNum() + otherGiveCoin);
            builder.setCoinReward(otherGiveCoin);
        } else {
            builder.setCoinReward(0);
        }
        long otherGiveScore = userData.getOtherGiveScore();
        if (otherGiveScore > 0) {
            userData.setOtherGiveScore(0);
        }
        builder.setRewardNum(userData.getOtherGiveRewardNum());
        userData.setOtherGiveRewardNum(0);
        builder.setRet(0);
        builder.setScoreReward(otherGiveScore);
        builder.setUserData(LangYaBangPb.parseLangYaBangUserData(userData, null, 0L));
        return builder;
    }

    public void syncWarReport(LangYaBangWarReportData warReportData, long userId, int server) {
        LangYaBangProto.LangYaWarReportSyncMsg.Builder syncBuilder = LangYaBangProto.LangYaWarReportSyncMsg.newBuilder();
        LangYaBangProto.LangYaNoticeData.Builder builder = LangYaBangPb.parseNoticeMsg(warReportData);
        syncBuilder.setActivityId(activityId);
        syncBuilder.setUserId(userId);
        syncBuilder.setData(builder);
        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(GameProtocol.S_LANG_YA_BANG_ACCEPT_CROSS_NOTICE, syncBuilder);
        MessageHelper.sendPacket(server, 0, pbMsg);
    }

    public LangYaBangProto.LangYaGetDeclareWarAllNoticeRespMsg.Builder getAllDeclareWarNotice() {
        LangYaBangProto.LangYaGetDeclareWarAllNoticeRespMsg.Builder builder = LangYaBangProto.LangYaGetDeclareWarAllNoticeRespMsg.newBuilder();
        builder.setRet(0);
        List<LangYaDeclareWarNoticeData> tmpList = new ArrayList<>();
        synchronized (noticeDataList){
            tmpList.addAll(noticeDataList);
        }
        for (LangYaDeclareWarNoticeData data : tmpList) {
            LangYaBangProto.LangYaDeclareWarNoticeData.Builder noticeMsg = LangYaBangPb.parseNoticeMsg(data);
            builder.addWarNoticeData(noticeMsg);
        }
        return builder;
    }

    public LangYaBangProto.LangYaBangGetNoOverDeclareWarListRespMsg.Builder getNoEndDeclareWar(long userId) {
        LangYaBangProto.LangYaBangGetNoOverDeclareWarListRespMsg.Builder builder = LangYaBangProto.LangYaBangGetNoOverDeclareWarListRespMsg.newBuilder();
        LangYaBangUserData userData = getUserData(userId);
        if (userData == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_CROSS_DATA_NO_INIT);
            return builder;
        }
        builder.setRet(0);
        String unionId = userData.getUnionId();
        Map<Integer, LangYaBangDeclareWarData> map = declareWarDataMap.get(unionId);
        if (map != null) {
            builder.addAllDeclareWarUid(map.keySet());
        }
        return builder;
    }

    public void reCalculateUserPatronsAbility(LangYaBangUserData userData) {
//        LangYaBangBuildingConfig totalLevelConfig = CrossLangYaBangConfigMgr.getBuildingTotalLevelConfig(activityId, userData.getBuildingLevel());
//        String addPowerFix = totalLevelConfig.getAddPowerFix();
//        int addPowerPro = totalLevelConfig.getAddPowerPro();
//        BigInteger bigAddPowerFix = new BigInteger(addPowerFix);
        if (userData.getUserPatronsInfoMap() != null) {
            for (LangYaTypePatrons typePatrons : userData.getUserPatronsInfoMap().values()) {
                BigInteger ability = typePatrons.getPatronsInfos().getAbility();
//                BigInteger buffAbility = ability.multiply(BigInteger.valueOf(1000 + addPowerPro)).divide(BigInteger.valueOf(1000)).add(bigAddPowerFix.multiply(BigInteger.valueOf(typePatrons.getPatronsInfos().size())));
//                typePatrons.setBuffAbility(buffAbility);
                //宣战的 进攻加成一下
                BigInteger declareWarAttackAbility = ability.multiply(BigInteger.valueOf(1000 + CrossLangYaBangConfigMgr.getConfig(activityId).getDeclareWarAttackAddition())).divide(BigInteger.valueOf(1000));
                typePatrons.setDeclareWarAttackAbility(declareWarAttackAbility);
            }
        }
    }

    public boolean checkCanOperateTime() {


        LangYaBangConfig config = CrossLangYaBangConfigMgr.getConfig(activityId);
        if (config == null) {
            return false;
        }
        long now = System.currentTimeMillis();

        long todayZeroTimeStamp = DateHelper.getTodayZeroTimeStamp();
        long startMill = todayZeroTimeStamp + DateHelper.MINUTE_MILLIONS * config.getOpenTime().get(0);
        long endMill = todayZeroTimeStamp + DateHelper.MINUTE_MILLIONS * config.getOpenTime().get(1);
        if (now >= startMill && now <= endMill) {
            return true;
        }
        return false;
    }

    public long getRandomPvpUserByRank(LangYaBangUserData userData){
        List<LangYaBangUserData> list = new ArrayList<>();
        synchronized (userDataMap){
            list = new ArrayList<>(userDataMap.values());
        }

        if (list.isEmpty()){
            return 0;
        }

        list.sort(Comparator.comparing(LangYaBangUserData::getHistoryCoinNum).reversed());
        int myRank = list.indexOf(userData);
        long resultId = 0;
        //第一次
        int startIndex = Math.max((myRank - 10), 0);
        int endIndex = Math.min((myRank+10),list.size());
        if (startIndex >= endIndex){
            return 0;
        }
        List<LangYaBangUserData> tmpSubList = new ArrayList<>(list.subList(startIndex,endIndex));
        resultId = getCanBattleUserInList(tmpSubList, userData);
        if (resultId != 0){
            return resultId;
        }
        //第二次
        int startIndex2 = Math.max((myRank - 20), 0);
        int endIndex2 = Math.min((myRank+20),list.size());
        if (startIndex2 >= endIndex2){
            return 0;
        }
        if (startIndex2 == startIndex && endIndex2 == endIndex){
            return 0;
        }
        tmpSubList = new ArrayList<>(list.subList(startIndex2,endIndex2));
        resultId = getCanBattleUserInList(tmpSubList, userData);
        if (resultId != 0){
            return resultId;
        }
        //第三次
        int startIndex3 = Math.max((myRank - 50), 0);
        int endIndex3 = Math.min((myRank+50),list.size());
        if (startIndex3 >= endIndex3){
            return 0;
        }
        if (startIndex3 == startIndex2 && endIndex3 == endIndex2){
            return 0;
        }
        tmpSubList = new ArrayList<>(list.subList(startIndex3,endIndex3));
        resultId = getCanBattleUserInList(tmpSubList, userData);
        if (resultId != 0){
            return resultId;
        }

        return 0;

    }

    public long getCanBattleUserInList(List<LangYaBangUserData> subList,LangYaBangUserData myUserData){
        //分是不是我的服务器的
        List<LangYaBangUserData> myServerUser = new ArrayList<>();
        List<LangYaBangUserData> otherServerUser = new ArrayList<>();
        int safeTime = 0;
        LangYaRollDiceConfig diceConfigByType = CrossLangYaBangConfigMgr.getRollDiceConfigByType(activityId, eLangYaBangEventType.pvp.getValue());
        if (diceConfigByType != null) {
            safeTime = diceConfigByType.getEventParamList().get(2);
        }
        for (LangYaBangUserData userData:subList){
            if (userData.getServerId() == myUserData.getServerId()){
                myServerUser.add(userData);
            }else {
                otherServerUser.add(userData);
            }
        }
        //乱序
        Collections.shuffle(myServerUser);
        Collections.shuffle(otherServerUser);
        LangYaBangUserData resultUser = null;
        //先去别区服找
        for (LangYaBangUserData userData:otherServerUser){
            //自己
            if (userData.getUserId() == myUserData.getUserId()){
                continue;
            }
            //商会里的
            if (Objects.equals(userData.getUnionId(),myUserData.getUnionId())){
                continue;
            }
            //保护期间
            long now = System.currentTimeMillis();
            if ((userData.getLastBeenBeatTime() + safeTime * DateHelper.SECOND_MILLIONS) > now){
                continue;
            }
            resultUser = userData;
            break;
        }
        if (resultUser != null){
            return resultUser.getUserId();
        }
        //没有再去自己区服找
        for (LangYaBangUserData userData : myServerUser) {
            //自己
            if (userData.getUserId() == myUserData.getUserId()) {
                continue;
            }
            //商会里的
            if (Objects.equals(userData.getUnionId(), myUserData.getUnionId())) {
                continue;
            }
            //保护期间
            long now = System.currentTimeMillis();
            if ((userData.getLastBeenBeatTime() + safeTime * DateHelper.SECOND_MILLIONS) > now) {
                continue;
            }
            resultUser = userData;
            break;
        }
        if (resultUser != null){
            return resultUser.getUserId();
        } else {
            return 0;
        }
    }

    /**
     * 修改自动处理开关
     */

    public LangYaBangProto.LangYaBangSetAutoSwitchRespMsg.Builder updateAutoSwitch(long userId,List<Integer> autoSwitchList){
        LangYaBangProto.LangYaBangSetAutoSwitchRespMsg.Builder builder = LangYaBangProto.LangYaBangSetAutoSwitchRespMsg.newBuilder();
        LangYaBangUserData userData = getUserData(userId);
        if (userData == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_CROSS_DATA_NO_INIT);
            return builder;
        }
        LangYaBangConfig config = CrossLangYaBangConfigMgr.getConfig(activityId);
        if (config == null) {
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_CONFIG_ERROR);
            return builder;
        }
        if (userData.getHasAllUsedPower() < config.getAutoNeedPower()){
            builder.setRet(GameErrorCode.E_LANG_YA_BANG_SCORE_NOT_ENOUGH);
            return builder;
        }
        userData.setOpenSwitchList(autoSwitchList);
        builder.setRet(0);
        return builder;
    }

}
